""" WebSocket连接管理器 — 支持 workspace 隔离 """ from typing import Dict, Set, Optional from fastapi import WebSocket import json class WebSocketManager: """WebSocket连接管理器(workspace 感知)""" def __init__(self): # execution_id -> Set[WebSocket] self.active_connections: Dict[str, Set[WebSocket]] = {} # websocket -> workspace_id (用于 workspace 隔离广播) self._ws_workspace: Dict[int, str] = {} async def connect( self, websocket: WebSocket, execution_id: str, workspace_id: Optional[str] = None ): """建立 WebSocket 连接,标记 workspace。""" await websocket.accept() if execution_id not in self.active_connections: self.active_connections[execution_id] = set() self.active_connections[execution_id].add(websocket) if workspace_id: self._ws_workspace[id(websocket)] = workspace_id def disconnect(self, websocket: WebSocket, execution_id: str): """断开 WebSocket 连接,清理 workspace 标记。""" self._ws_workspace.pop(id(websocket), None) if execution_id in self.active_connections: self.active_connections[execution_id].discard(websocket) if not self.active_connections[execution_id]: del self.active_connections[execution_id] def get_workspace_id(self, websocket: WebSocket) -> Optional[str]: """获取连接关联的 workspace_id。""" return self._ws_workspace.get(id(websocket)) async def send_personal_message(self, message: dict, websocket: WebSocket): """ 发送个人消息 Args: message: 消息内容 websocket: WebSocket连接 """ try: await websocket.send_json(message) except Exception as e: print(f"发送WebSocket消息失败: {e}") async def broadcast_to_execution(self, execution_id: str, message: dict): """ 向特定执行的所有连接广播消息 Args: execution_id: 执行记录ID message: 消息内容 """ if execution_id not in self.active_connections: return # 需要断开连接的连接 disconnected = set() for websocket in self.active_connections[execution_id]: try: await websocket.send_json(message) except Exception as e: print(f"广播消息失败: {e}") disconnected.add(websocket) # 移除断开的连接 for websocket in disconnected: self.disconnect(websocket, execution_id) # 全局WebSocket管理器实例 websocket_manager = WebSocketManager()