"""WebSocket 连接管理与广播""" import asyncio from typing import List from starlette.websockets import WebSocket, WebSocketState class ConnectionManager: def __init__(self) -> None: self._connections: List[WebSocket] = [] self._lock = asyncio.Lock() @property def connection_count(self) -> int: return len(self._connections) async def connect(self, websocket: WebSocket) -> None: async with self._lock: self._connections.append(websocket) async def disconnect(self, websocket: WebSocket) -> None: async with self._lock: if websocket in self._connections: self._connections.remove(websocket) async def broadcast_json(self, payload: dict) -> None: async with self._lock: targets = list(self._connections) stale: List[WebSocket] = [] for ws in targets: try: if ws.client_state != WebSocketState.CONNECTED: stale.append(ws) continue await ws.send_json(payload) except Exception: stale.append(ws) if stale: async with self._lock: for ws in stale: if ws in self._connections: self._connections.remove(ws) async def disconnect_all(self) -> None: async with self._lock: targets = list(self._connections) self._connections.clear() for ws in targets: try: await ws.close() except Exception: pass