Browse Source

replace eventsource with reconnecting-eventsource to optimize the code.

(cherry picked from commit 505f86d75cca4005af05bf992d4feafc92dd5421)
aheizi 11 months ago
parent
commit
3975c8d8a9
3 changed files with 22 additions and 30 deletions
  1. 10 1
      package-lock.json
  2. 1 1
      package.json
  3. 11 28
      src/services/mcp/McpHub.ts

+ 10 - 1
package-lock.json

@@ -30,7 +30,6 @@
 				"delay": "^6.0.0",
 				"diff": "^5.2.0",
 				"diff-match-patch": "^1.0.5",
-				"eventsource": "^3.0.5",
 				"fast-deep-equal": "^3.1.3",
 				"fastest-levenshtein": "^1.0.16",
 				"get-folder-size": "^5.0.0",
@@ -48,6 +47,7 @@
 				"pretty-bytes": "^6.1.1",
 				"puppeteer-chromium-resolver": "^23.0.0",
 				"puppeteer-core": "^23.4.0",
+				"reconnecting-eventsource": "^1.6.4",
 				"serialize-error": "^11.0.3",
 				"simple-git": "^3.27.0",
 				"sound-play": "^1.1.0",
@@ -13359,6 +13359,15 @@
 				"url": "https://paulmillr.com/funding/"
 			}
 		},
+		"node_modules/reconnecting-eventsource": {
+			"version": "1.6.4",
+			"resolved": "https://registry.npmjs.org/reconnecting-eventsource/-/reconnecting-eventsource-1.6.4.tgz",
+			"integrity": "sha512-0L3IS3wxcNFApTPPHkcbY8Aya7XZIpYDzhxa8j6QSufVkUN018XJKfh2ZaThLBGP/iN5UTz2yweMhkqr0PKa7A==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=12.0.0"
+			}
+		},
 		"node_modules/reflect.getprototypeof": {
 			"version": "1.0.8",
 			"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz",

+ 1 - 1
package.json

@@ -333,7 +333,6 @@
 		"delay": "^6.0.0",
 		"diff": "^5.2.0",
 		"diff-match-patch": "^1.0.5",
-		"eventsource": "^3.0.5",
 		"fast-deep-equal": "^3.1.3",
 		"fastest-levenshtein": "^1.0.16",
 		"get-folder-size": "^5.0.0",
@@ -351,6 +350,7 @@
 		"pretty-bytes": "^6.1.1",
 		"puppeteer-chromium-resolver": "^23.0.0",
 		"puppeteer-core": "^23.4.0",
+		"reconnecting-eventsource": "^1.6.4",
 		"serialize-error": "^11.0.3",
 		"simple-git": "^3.27.0",
 		"sound-play": "^1.1.0",

+ 11 - 28
src/services/mcp/McpHub.ts

@@ -1,7 +1,7 @@
 import { Client } from "@modelcontextprotocol/sdk/client/index.js"
 import { StdioClientTransport, StdioServerParameters } from "@modelcontextprotocol/sdk/client/stdio.js"
 import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"
-import { EventSource } from "eventsource"
+import ReconnectingEventSource from "reconnecting-eventsource"
 import {
 	CallToolResultSchema,
 	ListResourcesResultSchema,
@@ -243,8 +243,16 @@ export class McpHub {
 						headers: config.headers,
 					},
 				}
-				global.EventSource = EventSource
-				transport = new SSEClientTransport(new URL(config.url), sseOptions)
+				// Configure ReconnectingEventSource options
+				const reconnectingEventSourceOptions = {
+					max_retry_time: 5000, // Maximum retry time in milliseconds
+					withCredentials: config.headers?.["Authorization"] ? true : false, // Enable credentials if Authorization header exists
+				}
+				global.EventSource = ReconnectingEventSource
+				transport = new SSEClientTransport(new URL(config.url), {
+					...sseOptions,
+					eventSourceInit: reconnectingEventSourceOptions,
+				})
 
 				// Set up SSE specific error handling
 				transport.onerror = async (error) => {
@@ -255,11 +263,6 @@ export class McpHub {
 						this.appendErrorMessage(connection, error.message)
 					}
 					await this.notifyWebviewOfServerChanges()
-
-					// Attempt reconnection for SSE
-					if (!this.isDisposed) {
-						await this.handleSSEReconnection(name, config)
-					}
 				}
 			}
 
@@ -295,26 +298,6 @@ export class McpHub {
 		}
 	}
 
-	private async handleSSEReconnection(name: string, config: z.infer<typeof ServerConfigSchema>): Promise<void> {
-		const maxRetries = 3
-		let retryCount = 0
-
-		while (retryCount < maxRetries) {
-			try {
-				await delay(Math.pow(2, retryCount) * 1000) // Exponential backoff
-				await this.connectToServer(name, config)
-				return
-			} catch (error) {
-				retryCount++
-				console.error(`Retry ${retryCount} failed for ${name}:`, error)
-			}
-		}
-
-		vscode.window.showErrorMessage(
-			`Failed to reconnect to ${name} after ${maxRetries} attempts. Please check your connection.`,
-		)
-	}
-
 	private appendErrorMessage(connection: McpConnection, error: string) {
 		const newError = connection.server.error ? `${connection.server.error}\n${error}` : error
 		connection.server.error = newError //.slice(0, 800)