@deepracticex/mcp-client
Advanced tools
| /** | ||
| * 简化的 WebSocket Transport Implementation | ||
| * | ||
| * 通过 WebSocket 与 MCP 服务器进行双向通信 | ||
| */ | ||
| import { EventEmitter } from 'events'; | ||
| import type { WebSocketTransportConfig, JsonRpcRequest, JsonRpcResponse } from '../types/index.js'; | ||
| export declare class WebSocketTransport extends EventEmitter { | ||
| private config; | ||
| private ws; | ||
| private connected; | ||
| private pendingRequests; | ||
| constructor(config: WebSocketTransportConfig); | ||
| connect(): Promise<void>; | ||
| sendRequest(request: JsonRpcRequest): Promise<JsonRpcResponse>; | ||
| close(): Promise<void>; | ||
| isConnected(): boolean; | ||
| private createWebSocketConnection; | ||
| private setupWebSocketHandlers; | ||
| private handleMessage; | ||
| private cleanup; | ||
| } | ||
| //# sourceMappingURL=WebSocketTransport.d.ts.map |
| {"version":3,"file":"WebSocketTransport.d.ts","sourceRoot":"","sources":["../../src/transport/WebSocketTransport.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEnG,qBAAa,kBAAmB,SAAQ,YAAY;IAStC,OAAO,CAAC,MAAM;IAR1B,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAIlB;gBAEe,MAAM,EAAE,wBAAwB;IAI9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAaxB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IA0B9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4C5B,WAAW,IAAI,OAAO;YAIR,yBAAyB;IAsBvC,OAAO,CAAC,sBAAsB;IAiC9B,OAAO,CAAC,aAAa;IA2BrB,OAAO,CAAC,OAAO;CAchB"} |
| /** | ||
| * 简化的 WebSocket Transport Implementation | ||
| * | ||
| * 通过 WebSocket 与 MCP 服务器进行双向通信 | ||
| */ | ||
| import WebSocket from 'ws'; | ||
| import { EventEmitter } from 'events'; | ||
| export class WebSocketTransport extends EventEmitter { | ||
| constructor(config) { | ||
| super(); | ||
| this.config = config; | ||
| this.ws = null; | ||
| this.connected = false; | ||
| this.pendingRequests = new Map(); | ||
| } | ||
| async connect() { | ||
| if (this.isConnected()) { | ||
| return; | ||
| } | ||
| try { | ||
| await this.createWebSocketConnection(); | ||
| this.connected = true; | ||
| } | ||
| catch (error) { | ||
| throw new Error(`Failed to connect to WebSocket server: ${error}`); | ||
| } | ||
| } | ||
| async sendRequest(request) { | ||
| if (!this.isConnected()) { | ||
| throw new Error('Not connected'); | ||
| } | ||
| return new Promise((resolve, reject) => { | ||
| // 设置请求超时 | ||
| const timeout = setTimeout(() => { | ||
| this.pendingRequests.delete(request.id); | ||
| reject(new Error(`Request timeout: ${request.method}`)); | ||
| }, 30000); | ||
| this.pendingRequests.set(request.id, { resolve, reject, timeout }); | ||
| // 发送请求 | ||
| const message = JSON.stringify(request); | ||
| this.ws.send(message, (error) => { | ||
| if (error) { | ||
| this.pendingRequests.delete(request.id); | ||
| clearTimeout(timeout); | ||
| reject(new Error(`Failed to send request: ${error.message}`)); | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
| async close() { | ||
| if (!this.ws) { | ||
| return; | ||
| } | ||
| try { | ||
| // 清理所有待处理的请求 | ||
| Array.from(this.pendingRequests.entries()).forEach(([id, { reject, timeout }]) => { | ||
| clearTimeout(timeout); | ||
| reject(new Error('Connection closed')); | ||
| }); | ||
| this.pendingRequests.clear(); | ||
| // 关闭 WebSocket | ||
| await new Promise((resolve) => { | ||
| if (!this.ws) { | ||
| resolve(); | ||
| return; | ||
| } | ||
| const timeout = setTimeout(() => { | ||
| this.cleanup(); | ||
| resolve(); | ||
| }, 5000); | ||
| this.ws.once('close', () => { | ||
| clearTimeout(timeout); | ||
| resolve(); | ||
| }); | ||
| if (this.ws.readyState === WebSocket.OPEN) { | ||
| this.ws.close(1000, 'Client closing connection'); | ||
| } | ||
| else { | ||
| resolve(); | ||
| } | ||
| }); | ||
| this.cleanup(); | ||
| this.emit('close'); | ||
| } | ||
| catch (error) { | ||
| // 忽略关闭错误 | ||
| } | ||
| } | ||
| isConnected() { | ||
| return this.connected && this.ws !== null && this.ws.readyState === WebSocket.OPEN; | ||
| } | ||
| async createWebSocketConnection() { | ||
| return new Promise((resolve, reject) => { | ||
| try { | ||
| this.ws = new WebSocket(this.config.url, { | ||
| headers: this.config.headers | ||
| }); | ||
| this.ws.once('open', () => { | ||
| this.setupWebSocketHandlers(); | ||
| resolve(); | ||
| }); | ||
| this.ws.once('error', (error) => { | ||
| reject(error); | ||
| }); | ||
| } | ||
| catch (error) { | ||
| reject(error); | ||
| } | ||
| }); | ||
| } | ||
| setupWebSocketHandlers() { | ||
| if (!this.ws) | ||
| return; | ||
| // 消息处理 | ||
| this.ws.on('message', (data) => { | ||
| try { | ||
| const message = data.toString('utf-8'); | ||
| this.handleMessage(message); | ||
| } | ||
| catch (error) { | ||
| console.error('Failed to process WebSocket message:', error); | ||
| } | ||
| }); | ||
| // 错误处理 | ||
| this.ws.on('error', (error) => { | ||
| console.error('WebSocket error:', error); | ||
| this.cleanup(); | ||
| this.emit('error', error); | ||
| }); | ||
| // 关闭处理 | ||
| this.ws.on('close', (code, reason) => { | ||
| console.log(`WebSocket closed with code ${code}, reason ${reason}`); | ||
| this.cleanup(); | ||
| this.emit('close'); | ||
| }); | ||
| // Ping/Pong 处理(保持连接活跃) | ||
| this.ws.on('ping', (data) => { | ||
| this.ws?.pong(data); | ||
| }); | ||
| } | ||
| handleMessage(message) { | ||
| try { | ||
| const parsed = JSON.parse(message); | ||
| if (parsed.id !== undefined) { | ||
| // 这是一个响应 | ||
| const pending = this.pendingRequests.get(parsed.id); | ||
| if (pending) { | ||
| clearTimeout(pending.timeout); | ||
| this.pendingRequests.delete(parsed.id); | ||
| if (parsed.error) { | ||
| pending.reject(new Error(parsed.error.message)); | ||
| } | ||
| else { | ||
| pending.resolve(parsed); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| // 这是一个通知,暂时忽略 | ||
| console.log('Received notification:', parsed); | ||
| } | ||
| } | ||
| catch (error) { | ||
| console.error('Failed to parse message:', error, 'Message:', message); | ||
| } | ||
| } | ||
| cleanup() { | ||
| if (this.ws) { | ||
| this.ws.removeAllListeners(); | ||
| // 强制关闭连接 | ||
| if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) { | ||
| this.ws.terminate(); | ||
| } | ||
| this.ws = null; | ||
| } | ||
| this.connected = false; | ||
| } | ||
| } | ||
| //# sourceMappingURL=WebSocketTransport.js.map |
| {"version":3,"file":"WebSocketTransport.js","sourceRoot":"","sources":["../../src/transport/WebSocketTransport.ts"],"names":[],"mappings":"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"} |
+1
-1
| { | ||
| "name": "@deepracticex/mcp-client", | ||
| "version": "1.0.2", | ||
| "version": "1.0.3", | ||
| "description": "MCP (Model Context Protocol) client for DeeChat - Simplified domain-rich model implementation for managing MCP server connections, tools, resources, and prompts", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
110286
13.21%37
12.12%1788
12.59%