from fastapi import WebSocket from typing import Dict, List import json import logging logger = logging.getLogger(__name__) class WebSocketManager: def __init__(self): self.active_connections: Dict[str, List[WebSocket]] = {} async def connect(self, websocket: WebSocket, meeting_id: str): await websocket.accept() if meeting_id not in self.active_connections: self.active_connections[meeting_id] = [] self.active_connections[meeting_id].append(websocket) logger.info(f"WebSocket connected: meeting={meeting_id}, total={len(self.active_connections[meeting_id])}") def disconnect(self, websocket: WebSocket, meeting_id: str): if meeting_id in self.active_connections: try: self.active_connections[meeting_id].remove(websocket) except ValueError: pass logger.info(f"WebSocket disconnected: meeting={meeting_id}") async def send_message(self, meeting_id: str, message: dict): if meeting_id not in self.active_connections: return disconnected = [] for ws in self.active_connections[meeting_id]: try: await ws.send_text(json.dumps(message, ensure_ascii=False)) except Exception as e: logger.warning(f"WebSocket send error for meeting {meeting_id}: {e}") disconnected.append(ws) for ws in disconnected: self.active_connections[meeting_id].remove(ws) async def broadcast_status(self, meeting_id: str, status: str, data: dict = None): message = { "type": "status_update", "meeting_id": meeting_id, "status": status, "data": data or {}, } await self.send_message(meeting_id, message) manager = WebSocketManager()