mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-07-09 06:21:57 +08:00
优化 SSE 管理器
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)!
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user