init
This commit is contained in:
46
backend/ws.py
Normal file
46
backend/ws.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""WS-Hub (R1): EINE Queue + EIN Sender-Task — Broadcasts bleiben geordnet.
|
||||
Payload ist nur ein dirty-Signal {typ, topic, bereich}; der Client lädt selbst."""
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
|
||||
class Hub:
|
||||
def __init__(self) -> None:
|
||||
self._clients: set = set()
|
||||
self._queue: asyncio.Queue | None = None
|
||||
self._loop: asyncio.AbstractEventLoop | None = None
|
||||
|
||||
def bind_loop(self, loop: asyncio.AbstractEventLoop) -> None:
|
||||
self._loop = loop
|
||||
self._queue = asyncio.Queue()
|
||||
loop.create_task(self._sende_schleife())
|
||||
|
||||
def push(self, tabelle: str, row: dict) -> None:
|
||||
"""Thread-sicher aus der DB-Schicht aufrufbar."""
|
||||
if self._loop is None or self._queue is None:
|
||||
return
|
||||
bereich = {"tasks": "graph", "gate_laeufe": "graph", "befunde": "graph",
|
||||
"runs": "run", "topics": "run"}.get(tabelle, "graph")
|
||||
msg = json.dumps({"typ": "dirty", "bereich": bereich}, ensure_ascii=False)
|
||||
self._loop.call_soon_threadsafe(self._queue.put_nowait, msg)
|
||||
|
||||
async def _sende_schleife(self) -> None:
|
||||
while True:
|
||||
msg = await self._queue.get()
|
||||
tot = []
|
||||
for ws in list(self._clients):
|
||||
try:
|
||||
await ws.send_text(msg)
|
||||
except Exception:
|
||||
tot.append(ws)
|
||||
for ws in tot:
|
||||
self._clients.discard(ws)
|
||||
|
||||
def connect(self, ws) -> None:
|
||||
self._clients.add(ws)
|
||||
|
||||
def disconnect(self, ws) -> None:
|
||||
self._clients.discard(ws)
|
||||
|
||||
|
||||
hub = Hub()
|
||||
Reference in New Issue
Block a user