UNPKG

dynamic-interaction

Version:

Dynamic interaction 动态交互mcp,用于cursor、windsurf、trae 等 AI 智能编辑器 Agent 运行时交互使用

155 lines (154 loc) 5.63 kB
"use strict"; /** * WebSocket 连接管理 * 负责管理WebSocket连接的生命周期 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.webSocketManager = exports.WebSocketManager = void 0; const ws_1 = require("ws"); const logger_1 = require("../../logger"); const errors_1 = require("../utils/errors"); const crypto_1 = require("crypto"); class WebSocketManager { static instance; wss = null; connections = new Map(); constructor() { } static getInstance() { if (!WebSocketManager.instance) { WebSocketManager.instance = new WebSocketManager(); } return WebSocketManager.instance; } initialize(server) { if (this.wss) { logger_1.logger.warn('WebSocket服务器已经初始化'); return; } this.wss = new ws_1.WebSocketServer({ server }); (0, logger_1.setWebSocketServer)(this.wss); logger_1.logger.info('WebSocket服务器已附加到HTTP服务器'); this.setupEventHandlers(); } setupEventHandlers() { if (!this.wss) return; this.wss.on('connection', (ws) => { const connectionId = this.addConnection(ws); logger_1.logger.info(`新客户端连接成功,连接ID: ${connectionId}`); // 设置连接事件处理器 this.setupConnectionHandlers(ws, connectionId); }); } setupConnectionHandlers(ws, connectionId) { ws.on('message', (message) => { this.updateConnectionActivity(connectionId); this.handleMessage(ws, message); }); ws.on('close', () => { logger_1.logger.info(`客户端连接已关闭,连接ID: ${connectionId}`); this.removeConnection(connectionId); this.handleDisconnection(ws); }); ws.on('error', (error) => { logger_1.logger.error(`WebSocket连接出错,连接ID: ${connectionId}:`, error); this.removeConnection(connectionId); this.handleDisconnection(ws); }); ws.on('pong', () => { this.updateConnectionActivity(connectionId); }); } addConnection(ws) { const connectionId = (0, crypto_1.randomUUID)(); const now = Date.now(); const connectionInfo = { id: connectionId, ws, connectedAt: now, lastActivity: now }; this.connections.set(connectionId, connectionInfo); return connectionId; } removeConnection(connectionId) { this.connections.delete(connectionId); } updateConnectionActivity(connectionId) { const connection = this.connections.get(connectionId); if (connection) { connection.lastActivity = Date.now(); } } handleMessage(ws, message) { try { const messageStr = Buffer.isBuffer(message) ? message.toString() : message instanceof ArrayBuffer ? Buffer.from(message).toString() : Array.isArray(message) ? Buffer.concat(message).toString() : String(message); const parsedMessage = JSON.parse(messageStr); logger_1.logger.debug('收到WebSocket消息:', parsedMessage); // 导入消息处理器(避免循环依赖) const { messageProcessor } = require('../messaging/processor'); messageProcessor.process(ws, parsedMessage); } catch (error) { logger_1.logger.error('解析WebSocket消息失败:', error); const errorResponse = { type: 'error', data: { message: 'JSON解析失败', code: errors_1.ErrorCodes.JSON_PARSE_ERROR } }; ws.send(JSON.stringify(errorResponse)); } } handleDisconnection(ws) { // 导入会话管理器(避免循环依赖) const { sessionManager } = require('../session/manager'); sessionManager.handleDisconnection(ws); // 检查服务器空闲状态 const { lifecycleManager } = require('../core/lifecycle'); lifecycleManager.checkAndStopIfIdle(); } getAvailableConnection() { // 导入会话管理器(避免循环依赖) const { sessionManager } = require('../session/manager'); for (const connection of this.connections.values()) { if (!sessionManager.hasSession(connection.ws)) { return connection.ws; } } return null; } getConnectionCount() { return this.connections.size; } getConnections() { return Array.from(this.connections.values()); } closeAll() { logger_1.logger.info(`关闭所有WebSocket连接 (${this.connections.size}个)`); for (const connection of this.connections.values()) { try { connection.ws.close(); } catch (error) { logger_1.logger.error(`关闭WebSocket连接失败:`, error); } } this.connections.clear(); } startHeartbeat(intervalMs = 30000) { setInterval(() => { for (const connection of this.connections.values()) { if (connection.ws.readyState === ws_1.WebSocket.OPEN) { connection.ws.ping(); } } }, intervalMs); } } exports.WebSocketManager = WebSocketManager; exports.webSocketManager = WebSocketManager.getInstance();