Files
home_hub/backend/app/core/broadcaster.py
T
gilles ec87bc091d feat(sse): sync temps réel multi-appareils via Server-Sent Events v0.5.8
- Broadcaster asyncio.Queue avec keepalive 25s (prévient timeout proxy)
- Endpoint GET /api/events/stream (StreamingResponse text/event-stream)
- Broadcast notes_changed / todos_changed / shopping_changed sur toutes mutations
- Hook useServerEvents: EventSource avec reconnexion automatique (3s)
- Pages Notes, Todos, Shopping abonnées aux événements SSE
- nginx: location SSE dédiée (proxy_buffering off, timeout 24h)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 20:12:02 +02:00

37 lines
1.0 KiB
Python

import asyncio
import json
from typing import AsyncGenerator
class EventBroadcaster:
def __init__(self):
self._queues: set[asyncio.Queue] = set()
async def subscribe(self) -> AsyncGenerator[str, None]:
queue: asyncio.Queue[str] = asyncio.Queue(maxsize=32)
self._queues.add(queue)
try:
while True:
try:
msg = await asyncio.wait_for(queue.get(), timeout=25)
yield msg
except asyncio.TimeoutError:
yield ": keepalive\n\n"
except asyncio.CancelledError:
pass
finally:
self._queues.discard(queue)
def broadcast(self, event_type: str, data: dict | None = None) -> None:
if not self._queues:
return
msg = f"event: {event_type}\ndata: {json.dumps(data or {})}\n\n"
for queue in list(self._queues):
try:
queue.put_nowait(msg)
except asyncio.QueueFull:
pass
broadcaster = EventBroadcaster()