mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 00:36:41 +08:00
优化 SSE 管理器
This commit is contained in:
@@ -165,8 +165,9 @@ function handleCurrentFileProgressMessage(event: MessageEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用优化的进度SSE连接 - 整体进度
|
// 使用优化的进度SSE连接 - 整体进度
|
||||||
|
const overallProgressUrl = `${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`
|
||||||
const overallProgressSSE = useProgressSSE(
|
const overallProgressSSE = useProgressSSE(
|
||||||
`${import.meta.env.VITE_API_BASE_URL}system/progress/filetransfer`,
|
overallProgressUrl,
|
||||||
handleOverallProgressMessage,
|
handleOverallProgressMessage,
|
||||||
'transfer-queue-overall-progress',
|
'transfer-queue-overall-progress',
|
||||||
progressActive,
|
progressActive,
|
||||||
@@ -184,10 +185,14 @@ function startCurrentFileProgress(filePath: string) {
|
|||||||
if (filePath) {
|
if (filePath) {
|
||||||
// filePath计算md5
|
// filePath计算md5
|
||||||
const filePathMd5 = CryptoJS.MD5(filePath).toString()
|
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(
|
currentFileProgressSSE = useProgressSSE(
|
||||||
`${import.meta.env.VITE_API_BASE_URL}system/progress/${filePathMd5}`,
|
currentFileProgressUrl,
|
||||||
handleCurrentFileProgressMessage,
|
handleCurrentFileProgressMessage,
|
||||||
'transfer-queue-current-file-progress',
|
uniqueListenerId,
|
||||||
progressActive,
|
progressActive,
|
||||||
)
|
)
|
||||||
currentFileProgressSSE.start()
|
currentFileProgressSSE.start()
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ export function useBackgroundOptimization() {
|
|||||||
connectDelay?: number // 新增:连接延迟
|
connectDelay?: number // 新增:连接延迟
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
const manager = sseManagerSingleton.getManager(url, options)
|
// 使用独立的SSE管理器,确保每个监听器都有独立的连接
|
||||||
|
const manager = sseManagerSingleton.getIndependentManager(url, listenerId, options)
|
||||||
const isConnected = ref(false)
|
const isConnected = ref(false)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -101,7 +102,8 @@ export function useBackgroundOptimization() {
|
|||||||
delay: number = 3000,
|
delay: number = 3000,
|
||||||
options?: Parameters<typeof useSSE>[3],
|
options?: Parameters<typeof useSSE>[3],
|
||||||
) => {
|
) => {
|
||||||
const manager = sseManagerSingleton.getManager(url, options)
|
// 使用独立的SSE管理器,确保每个监听器都有独立的连接
|
||||||
|
const manager = sseManagerSingleton.getIndependentManager(url, listenerId, options)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -133,7 +135,8 @@ export function useBackgroundOptimization() {
|
|||||||
listenerId: string,
|
listenerId: string,
|
||||||
isActive: Ref<boolean>,
|
isActive: Ref<boolean>,
|
||||||
) => {
|
) => {
|
||||||
const manager = sseManagerSingleton.getManager(url, {
|
// 使用独立的SSE管理器,确保每个监听器都有独立的连接
|
||||||
|
const manager = sseManagerSingleton.getIndependentManager(url, listenerId, {
|
||||||
backgroundCloseDelay: 1000, // 进度SSE更快关闭
|
backgroundCloseDelay: 1000, // 进度SSE更快关闭
|
||||||
reconnectDelay: 1000,
|
reconnectDelay: 1000,
|
||||||
maxReconnectAttempts: 5,
|
maxReconnectAttempts: 5,
|
||||||
|
|||||||
+31
-5
@@ -119,11 +119,12 @@ export class SSEManager {
|
|||||||
|
|
||||||
this.eventSource.onmessage = event => {
|
this.eventSource.onmessage = event => {
|
||||||
// 分发消息给所有监听器
|
// 分发消息给所有监听器
|
||||||
this.listeners.forEach(listener => {
|
this.listeners.forEach((listener, listenerId) => {
|
||||||
try {
|
try {
|
||||||
|
// 为每个监听器提供独立的错误处理
|
||||||
listener(event)
|
listener(event)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('SSE: 监听器错误', error)
|
console.error(`SSE: 监听器错误 [${listenerId}]`, error)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -245,12 +246,37 @@ class SSEManagerSingleton {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取或创建SSE管理器
|
* 获取或创建SSE管理器
|
||||||
|
* @param url SSE连接URL
|
||||||
|
* @param options SSE选项
|
||||||
|
* @returns SSE管理器实例
|
||||||
*/
|
*/
|
||||||
getManager(url: string, options?: ConstructorParameters<typeof SSEManager>[1]): SSEManager {
|
getManager(url: string, options?: ConstructorParameters<typeof SSEManager>[1]): SSEManager {
|
||||||
if (!this.managers.has(url)) {
|
// 使用完整的URL作为key,确保不同路径的SSE连接不会复用
|
||||||
this.managers.set(url, new SSEManager(url, options))
|
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