replace eventsource with reconnecting-eventsource to optimize the code.

(cherry picked from commit 505f86d75c)
This commit is contained in:
aheizi 2025-03-12 19:23:33 +08:00
parent 6f5ce14586
commit 3975c8d8a9
3 changed files with 22 additions and 30 deletions

11
package-lock.json generated
View file

@ -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",

View file

@ -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",

View file

@ -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)