diff --git a/frontend/src/composables/useWebSocket.ts b/frontend/src/composables/useWebSocket.ts index 91b5e83..d44ce09 100644 --- a/frontend/src/composables/useWebSocket.ts +++ b/frontend/src/composables/useWebSocket.ts @@ -93,7 +93,7 @@ const initGlobalStorage = (): GlobalWSStorage => { // 获取全局存储 const getGlobalStorage = (): GlobalWSStorage => { if (!(window as any)[WS_STORAGE_KEY]) { - ;(window as any)[WS_STORAGE_KEY] = initGlobalStorage() + ; (window as any)[WS_STORAGE_KEY] = initGlobalStorage() } return (window as any)[WS_STORAGE_KEY] as GlobalWSStorage @@ -173,7 +173,7 @@ const handleBackendFailure = async () => { okText: '重启应用', onOk: () => { if ((window.electronAPI as any)?.windowClose) { - ;(window.electronAPI as any).windowClose() + ; (window.electronAPI as any).windowClose() } else { window.location.reload() } @@ -416,36 +416,8 @@ const createGlobalWebSocket = (): WebSocket => { /* ignore */ } - // 自动订阅ID为"Main"的消息,用于处理ping-pong等系统消息 - _subscribe('Main', { - onMessage: (message: WebSocketBaseMessage) => { - // 处理系统级消息(如ping-pong) - if (message && message.type === 'Signal' && message.data) { - // 处理心跳响应 - if (message.data.Pong) { - global.lastPingTime = 0 // 重置ping时间,表示收到了响应 - return - } - - // 处理后端发送的Ping,回复Pong - if (message.data.Ping) { - if (ws && ws.readyState === WebSocket.OPEN) { - try { - ws.send( - JSON.stringify({ - type: 'Signal', - data: { Pong: message.data.Ping, connectionId: global.connectionId }, - }) - ) - } catch (e) { - // Pong发送失败,静默处理 - } - } - return - } - } - }, - }) + // 初始化全局订阅(TaskManager和Main) + initializeGlobalSubscriptions() } ws.onmessage = ev => { @@ -604,6 +576,71 @@ window.addEventListener('beforeunload', () => { // 保持连接 }) +// 全局订阅处理函数 - 供调度台逻辑调用 +let globalTaskManagerHandler: ((message: any) => void) | null = null +let globalMainMessageHandler: ((message: any) => void) | null = null + +// 设置TaskManager消息处理函数 +export const setTaskManagerHandler = (handler: (message: any) => void) => { + globalTaskManagerHandler = handler +} + +// 设置Main消息处理函数 +export const setMainMessageHandler = (handler: (message: any) => void) => { + globalMainMessageHandler = handler +} + +// 初始化全局订阅 +const initializeGlobalSubscriptions = () => { + // 订阅TaskManager消息 + _subscribe('TaskManager', { + onMessage: (message) => { + if (globalTaskManagerHandler) { + globalTaskManagerHandler(message) + } + } + }) + + // 订阅Main消息 + _subscribe('Main', { + onMessage: (message) => { + // 处理系统级消息(如ping-pong) + if (message && message.type === 'Signal' && message.data) { + // 处理心跳响应 + if (message.data.Pong) { + const global = getGlobalStorage() + global.lastPingTime = 0 // 重置ping时间,表示收到了响应 + return + } + + // 处理后端发送的Ping,回复Pong + if (message.data.Ping) { + const global = getGlobalStorage() + const ws = global.wsRef + if (ws && ws.readyState === WebSocket.OPEN) { + try { + ws.send( + JSON.stringify({ + type: 'Signal', + data: { Pong: message.data.Ping, connectionId: global.connectionId }, + }) + ) + } catch (e) { + // Pong发送失败,静默处理 + } + } + return + } + } + + // 调用外部设置的Main消息处理函数 + if (globalMainMessageHandler) { + globalMainMessageHandler(message) + } + } + }) +} + // 主要 Hook 函数 export function useWebSocket() { const global = getGlobalStorage() @@ -699,7 +736,7 @@ export const _subscribe = (id: string, subscriber: Omit { console.log('[WebSocket] 开始处理遗留消息,订阅者ID:', id, '消息索引:', index, '消息:', queuedMessage.message) @@ -710,7 +747,7 @@ export const _subscribe = (id: string, subscriber: Omit 0) { console.log('[WebSocket] 共清理过期消息数量:', cleanedCount) setMessageQueue(messageQueue) diff --git a/frontend/src/views/scheduler/useSchedulerLogic.ts b/frontend/src/views/scheduler/useSchedulerLogic.ts index fe1e8ae..387b2cd 100644 --- a/frontend/src/views/scheduler/useSchedulerLogic.ts +++ b/frontend/src/views/scheduler/useSchedulerLogic.ts @@ -3,7 +3,7 @@ import { message, Modal, notification } from 'ant-design-vue' import { Service } from '@/api/services/Service' import { TaskCreateIn } from '@/api/models/TaskCreateIn' import { PowerIn } from '@/api/models/PowerIn' -import { useWebSocket } from '@/composables/useWebSocket' +import { useWebSocket, setTaskManagerHandler, setMainMessageHandler } from '@/composables/useWebSocket' import type { ComboBoxItem } from '@/api/models/ComboBoxItem' import type { QueueItem, Script } from './schedulerConstants' import { @@ -110,13 +110,7 @@ export function useSchedulerLogic() { // WebSocket 实例 const ws = useWebSocket() - // 订阅TaskManager消息,处理自动创建的任务 - const subscribeToTaskManager = () => { - ws.subscribe('TaskManager', { - onMessage: (message) => handleTaskManagerMessage(message) - }) - } - + // TaskManager消息处理函数(供全局WebSocket调用) const handleTaskManagerMessage = (wsMessage: any) => { if (!wsMessage || typeof wsMessage !== 'object') return @@ -772,13 +766,10 @@ export function useSchedulerLogic() { // 初始化函数 const initialize = () => { - // 订阅TaskManager消息 - subscribeToTaskManager() - console.log('[Scheduler] 已订阅TaskManager消息') - - // 订阅Main消息(用于接收全局消息如电源操作倒计时) - subscribeToMainMessages() - console.log('[Scheduler] 已订阅Main消息') + // 设置全局WebSocket的消息处理函数 + setTaskManagerHandler(handleTaskManagerMessage) + setMainMessageHandler(handleMainMessage) + console.log('[Scheduler] 已设置全局WebSocket消息处理函数') // 新增:为已有的“运行中”标签恢复 WebSocket 订阅,防止路由切换返回后不再更新 try { @@ -793,13 +784,7 @@ export function useSchedulerLogic() { } } - // 订阅Main消息,处理全局消息 - const subscribeToMainMessages = () => { - ws.subscribe('Main', { - onMessage: (message) => handleMainMessage(message) - }) - } - + // Main消息处理函数(供全局WebSocket调用) const handleMainMessage = (wsMessage: any) => { if (!wsMessage || typeof wsMessage !== 'object') return @@ -825,9 +810,9 @@ export function useSchedulerLogic() { powerCountdownTimer = null } - // 取消订阅TaskManager和Main - ws.unsubscribe('TaskManager') - ws.unsubscribe('Main') + // 清理全局WebSocket的消息处理函数 + setTaskManagerHandler(() => {}) + setMainMessageHandler(() => {}) schedulerTabs.value.forEach(tab => { if (tab.websocketId) {