Spaces:
Sleeping
Sleeping
| """WebSocket connection registry. | |
| Completely stateless about message content -> just tracks live sockets and | |
| broadcasts typed envelopes. Isolated so routers and handlers never import | |
| fastapi.WebSocket directly. | |
| """ | |
| from typing import Dict | |
| from fastapi import WebSocket, WebSocketDisconnect | |
| class ConnectionManager: | |
| def __init__(self) -> None: | |
| self._active: Dict[str, WebSocket] = {} | |
| async def connect(self, project_id: str, ws: WebSocket) -> None: | |
| await ws.accept() | |
| self._active[project_id] = ws | |
| def disconnect(self, project_id: str, ws: WebSocket | None = None) -> None: | |
| if ws is not None and self._active.get(project_id) is not ws: | |
| return | |
| self._active.pop(project_id, None) | |
| async def send(self, project_id: str, msg_type: str, data: dict) -> None: | |
| ws = self._active.get(project_id) | |
| if ws: | |
| try: | |
| await ws.send_json({"type": msg_type, "data": data}) | |
| except (RuntimeError, WebSocketDisconnect, OSError): | |
| self.disconnect(project_id, ws) | |
| def is_connected(self, project_id: str) -> bool: | |
| return project_id in self._active | |