Flask-SocketIO broadcasts from HTTP routes don't reach clients. After 50+ attempts with different emit methods, none work.
Instead of WebSocket broadcasts, poll the server for updates:
# models.py - Add to TaskCompletion model
class TaskCompletion(db.Model):
# ...existing fields...
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)# routes/api_routes.py
@api_bp.route('/api/pulse/<int:pulse_id>/updates')
@login_required
def get_pulse_updates(pulse_id):
"""Get recent task completion updates for a Pulse."""
since = request.args.get('since', type=float) # Unix timestamp
if not since:
return jsonify({'updates': []})
# Get all task completions for this pulse since timestamp
pulse_items = PulseItem.query.filter_by(pulse_id=pulse_id).all()
checklist_ids = [pi.checklist_id for pi in pulse_items if pi.checklist_id]
updates = []
for checklist_id in checklist_ids:
tasks = Task.query.filter_by(checklist_id=checklist_id).all()
for task in tasks:
completion = TaskCompletion.query.filter(
TaskCompletion.task_id == task.id,
TaskCompletion.user_id == current_user.id,
TaskCompletion.updated_at > datetime.fromtimestamp(since)
).first()
if completion:
updates.append({
'checklist_id': checklist_id,
'task_id': task.id,
'completed': completion.completed,
'completion_date': completion.completion_date.isoformat() if completion.completion_date else None
})
return jsonify({'updates': updates})// templates/base.html - replace WebSocket listener
let lastPollTime = Date.now() / 1000;
// Poll every 2 seconds for updates
setInterval(async function() {
if (window.location.pathname === '/') {
// Get all Pulses on current page
const pulseElements = document.querySelectorAll('[data-pulse-id]');
for (const element of pulseElements) {
const pulseId = element.dataset.pulseId;
try {
const response = await fetch(`/api/pulse/${pulseId}/updates?since=${lastPollTime}`);
const data = await response.json();
if (data.updates && data.updates.length > 0) {
// Refresh the checklists container
const urlParams = new URLSearchParams(window.location.search);
const currentDate = urlParams.get('date') || new Date().toISOString().split('T')[0];
htmx.ajax('GET', `/api/checklists?date=${currentDate}`, {
target: '#checklistsContainer',
swap: 'innerHTML'
});
console.log(`Updated ${data.updates.length} tasks from polling`);
break; // Only refresh once
}
} catch (error) {
console.error('Polling error:', error);
}
}
lastPollTime = Date.now() / 1000;
}
}, 2000); // Poll every 2 seconds- ✅ Actually works
- ✅ Simple to implement
- ✅ No WebSocket complexity
- ✅ Works across all browsers
- ❌ 2-second delay (vs instant)
- ❌ More server load (polling every 2s)
- Use Server-Sent Events (SSE) instead of polling
- Increase poll interval to 5s for less load
- Only poll when user is active (use page visibility API)