UNPKG

feishu-mcp

Version:

Model Context Protocol server for Feishu integration

105 lines (104 loc) 3.48 kB
import { Logger } from '../utils/logger.js'; /** * SSE连接管理器 - 负责管理所有的SSE长连接和心跳机制 */ export class SSEConnectionManager { constructor() { Object.defineProperty(this, "transports", { enumerable: true, configurable: true, writable: true, value: {} }); Object.defineProperty(this, "connections", { enumerable: true, configurable: true, writable: true, value: new Map() }); Object.defineProperty(this, "keepAliveIntervalId", { enumerable: true, configurable: true, writable: true, value: null }); Object.defineProperty(this, "KEEP_ALIVE_INTERVAL_MS", { enumerable: true, configurable: true, writable: true, value: 1000 * 25 }); // 25秒心跳间隔 this.startGlobalKeepAlive(); } /** * 启动全局心跳管理 */ startGlobalKeepAlive() { if (this.keepAliveIntervalId) { clearInterval(this.keepAliveIntervalId); } this.keepAliveIntervalId = setInterval(() => { Logger.info(`[KeepAlive] Sending keepalive to ${this.connections.size} connections`); for (const [sessionId, connection] of this.connections.entries()) { if (!connection.res.writableEnded) { connection.res.write(': keepalive\n\n'); } else { // 移除已关闭的连接 this.removeConnection(sessionId); } } }, this.KEEP_ALIVE_INTERVAL_MS); } /** * 添加新的SSE连接 */ addConnection(sessionId, transport, req, res) { this.transports[sessionId] = transport; this.connections.set(sessionId, { res }); console.info(`[SSE Connection] Client connected: ${sessionId}`); req.on('close', () => { this.removeConnection(sessionId); }); } /** * 移除SSE连接 */ removeConnection(sessionId) { const transport = this.transports[sessionId]; if (transport) { try { transport.close(); Logger.info(`[SSE Connection] Transport closed for: ${sessionId}`); } catch (error) { Logger.error(`[SSE Connection] Error closing transport for: ${sessionId}`, error); } } delete this.transports[sessionId]; this.connections.delete(sessionId); console.info(`[SSE Connection] Client disconnected: ${sessionId}`); } /** * 获取指定sessionId的传输实例 */ getTransport(sessionId) { console.info(`[SSE Connection] Getting transport for sessionId: ${sessionId}`); return this.transports[sessionId]; } /** * 关闭连接管理器 */ shutdown() { if (this.keepAliveIntervalId) { clearInterval(this.keepAliveIntervalId); this.keepAliveIntervalId = null; } // 关闭所有连接 Logger.info(`[SSE Connection] Shutting down all connections (${this.connections.size} active)`); for (const sessionId of this.connections.keys()) { this.removeConnection(sessionId); } Logger.info(`[SSE Connection] All connections closed`); } }