优化 SSE 管理器

This commit is contained in:
jxxghp
2025-08-24 17:34:43 +08:00
parent 79e4ecfdbe
commit 1af1a06700
3 changed files with 45 additions and 11 deletions

View File

@@ -165,8 +165,9 @@ function handleCurrentFileProgressMessage(event: MessageEvent) {
}
// 使用优化的进度SSE连接 - 整体进度
const overallProgressUrl = `${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`
const overallProgressSSE = useProgressSSE(
`${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`,
overallProgressUrl,
handleOverallProgressMessage,
'transfer-queue-overall-progress',
progressActive,
@@ -184,10 +185,14 @@ function startCurrentFileProgress(filePath: string) {
if (filePath) {
// filePath计算md5
const filePathMd5 = CryptoJS.MD5(filePath).toString()
// 使用包含文件路径的唯一监听器ID避免SSE管理器复用连接导致的消息串流
const uniqueListenerId = `transfer-queue-current-file-progress-${filePathMd5}`
const currentFileProgressUrl = `${import.meta.env.VITE_API_BASE_URL}system/progress/${filePathMd5}`
currentFileProgressSSE = useProgressSSE(
`${import.meta.env.VITE_API_BASE_URL}system/progress/${filePathMd5}`,
currentFileProgressUrl,
handleCurrentFileProgressMessage,
'transfer-queue-current-file-progress',
uniqueListenerId,
progressActive,
)
currentFileProgressSSE.start()

View File

@@ -25,7 +25,8 @@ export function useBackgroundOptimization() {
connectDelay?: number // 新增:连接延迟
},
) => {
const manager = sseManagerSingleton.getManager(url, options)
// 使用独立的SSE管理器确保每个监听器都有独立的连接
const manager = sseManagerSingleton.getIndependentManager(url, listenerId, options)
const isConnected = ref(false)
onMounted(() => {
@@ -101,7 +102,8 @@ export function useBackgroundOptimization() {
delay: number = 3000,
options?: Parameters<typeof useSSE>[3],
) => {
const manager = sseManagerSingleton.getManager(url, options)
// 使用独立的SSE管理器确保每个监听器都有独立的连接
const manager = sseManagerSingleton.getIndependentManager(url, listenerId, options)
onMounted(() => {
setTimeout(() => {
@@ -133,7 +135,8 @@ export function useBackgroundOptimization() {
listenerId: string,
isActive: Ref<boolean>,
) => {
const manager = sseManagerSingleton.getManager(url, {
// 使用独立的SSE管理器确保每个监听器都有独立的连接
const manager = sseManagerSingleton.getIndependentManager(url, listenerId, {
backgroundCloseDelay: 1000, // 进度SSE更快关闭
reconnectDelay: 1000,
maxReconnectAttempts: 5,

View File

@@ -119,11 +119,12 @@ export class SSEManager {
this.eventSource.onmessage = event => {
// 分发消息给所有监听器
this.listeners.forEach(listener => {
this.listeners.forEach((listener, listenerId) => {
try {
// 为每个监听器提供独立的错误处理
listener(event)
} catch (error) {
console.error('SSE: 监听器错误', error)
console.error(`SSE: 监听器错误 [${listenerId}]`, error)
}
})
}
@@ -245,12 +246,37 @@ class SSEManagerSingleton {
/**
* 获取或创建SSE管理器
* @param url SSE连接URL
* @param options SSE选项
* @returns SSE管理器实例
*/
getManager(url: string, options?: ConstructorParameters<typeof SSEManager>[1]): SSEManager {
if (!this.managers.has(url)) {
this.managers.set(url, new SSEManager(url, options))
// 使用完整的URL作为key确保不同路径的SSE连接不会复用
const managerKey = url
if (!this.managers.has(managerKey)) {
this.managers.set(managerKey, new SSEManager(url, options))
}
return this.managers.get(url)!
return this.managers.get(managerKey)!
}
/**
* 获取或创建独立的SSE管理器为每个监听器创建独立连接
* @param url SSE连接URL
* @param listenerId 监听器ID
* @param options SSE选项
* @returns SSE管理器实例
*/
getIndependentManager(
url: string,
listenerId: string,
options?: ConstructorParameters<typeof SSEManager>[1],
): SSEManager {
// 使用URL + 监听器ID作为key确保每个监听器都有独立的连接
const managerKey = `${url}::${listenerId}`
if (!this.managers.has(managerKey)) {
this.managers.set(managerKey, new SSEManager(url, options))
}
return this.managers.get(managerKey)!
}
/**