diff --git a/src/hooks/websocket/core/useStomp.ts b/src/hooks/websocket/core/useStomp.ts index 4a02a6ba..74897755 100644 --- a/src/hooks/websocket/core/useStomp.ts +++ b/src/hooks/websocket/core/useStomp.ts @@ -28,14 +28,13 @@ export interface UseStompOptions { export function useStomp(options: UseStompOptions = {}) { // 默认值:brokerURL 从环境变量中获取,token 从 getAccessToken() 获取 const defaultBrokerURL = import.meta.env.VITE_APP_WS_ENDPOINT || ""; - // 不再使用defaultToken,每次连接时直接获取最新token const brokerURL = ref(options.brokerURL ?? defaultBrokerURL); - // 不再存储token,改为在初始化时获取 - const reconnectDelay = options.reconnectDelay ?? 8000; + // 默认配置参数 + const reconnectDelay = options.reconnectDelay ?? 15000; // 默认15秒重连间隔 const connectionTimeout = options.connectionTimeout ?? 10000; const useExponentialBackoff = options.useExponentialBackoff ?? false; - const maxReconnectAttempts = options.maxReconnectAttempts ?? 5; + const maxReconnectAttempts = options.maxReconnectAttempts ?? 3; // 最多重连3次 const maxReconnectDelay = options.maxReconnectDelay ?? 60000; // 连接状态标记 @@ -76,7 +75,7 @@ export function useStomp(options: UseStompOptions = {}) { Authorization: `Bearer ${currentToken}`, }, debug: options.debug ? console.log : () => {}, - reconnectDelay: useExponentialBackoff ? 0 : reconnectDelay, // 使用自定义退避策略时禁用内置重连 + reconnectDelay: useExponentialBackoff ? 0 : reconnectDelay, // 禁用内置重连机制 heartbeatIncoming: 4000, heartbeatOutgoing: 4000, }); @@ -195,12 +194,19 @@ export function useStomp(options: UseStompOptions = {}) { initializeClient(); } - if (client.value && (client.value.connected || client.value.active)) { + if (!client.value) { + console.error("STOMP客户端初始化失败"); return; } - if (!client.value) { - console.error("STOMP客户端初始化失败"); + // 避免重复连接:检查是否已连接或正在连接 + if (client.value.connected) { + console.log("WebSocket已经连接,跳过重复连接"); + return; + } + + if (client.value.active) { + console.log("WebSocket连接正在进行中,跳过重复连接请求"); return; } diff --git a/src/hooks/websocket/services/useDictSync.ts b/src/hooks/websocket/services/useDictSync.ts index d37fa8ba..fa2257f3 100644 --- a/src/hooks/websocket/services/useDictSync.ts +++ b/src/hooks/websocket/services/useDictSync.ts @@ -24,9 +24,10 @@ function createDictSyncHook() { // 使用现有的useStomp,配置适合字典场景的重连参数 const { isConnected, connect, subscribe, unsubscribe, disconnect } = useStomp({ - reconnectDelay: 10000, // 使用更长的重连延迟 - 10秒 - connectionTimeout: 15000, // 更长的连接超时时间 - 15秒 - useExponentialBackoff: false, // 字典数据不需要指数退避策略 + reconnectDelay: 20000, // 字典更新重连时间 + connectionTimeout: 15000, // 连接超时阈值 + useExponentialBackoff: false, // 使用固定间隔重连策略 + maxReconnectAttempts: 3, // 最多重连3次 }); // 存储订阅ID @@ -101,8 +102,8 @@ function createDictSyncHook() { const attemptSubscribe = () => { if (!isConnected.value) { console.log("等待WebSocket连接建立..."); - // 3秒后再次尝试 - setTimeout(attemptSubscribe, 3000); + // 10秒后再次尝试 + setTimeout(attemptSubscribe, 10000); return; } diff --git a/src/hooks/websocket/services/useOnlineCount.ts b/src/hooks/websocket/services/useOnlineCount.ts index 20f8a749..4eae5471 100644 --- a/src/hooks/websocket/services/useOnlineCount.ts +++ b/src/hooks/websocket/services/useOnlineCount.ts @@ -28,9 +28,9 @@ export function useOnlineCount() { disconnect, isConnected: stompConnected, } = useStomp({ - reconnectDelay: 5000, // 初始重连延迟5秒 - maxReconnectAttempts: 3, // 最大重连3次 - connectionTimeout: 10000, // 连接超时10秒 + reconnectDelay: 15000, // 重连基础延迟 + maxReconnectAttempts: 3, // 重连次数上限 + connectionTimeout: 10000, // 连接超时 useExponentialBackoff: true, // 启用指数退避 }); @@ -56,7 +56,11 @@ export function useOnlineCount() { * 订阅在线用户计数主题 */ const subscribeToOnlineCount = () => { - if (!stompConnected.value) return; + if (!stompConnected.value) { + // 10秒后重试订阅 + setTimeout(subscribeToOnlineCount, 10000); + return; + } // 如果已经订阅,先取消订阅 if (subscriptionId) { diff --git a/src/plugins/websocket.ts b/src/plugins/websocket.ts index 890f438f..84745950 100644 --- a/src/plugins/websocket.ts +++ b/src/plugins/websocket.ts @@ -1,12 +1,28 @@ import { useDictSync } from "@/hooks/websocket/services/useDictSync"; import { getAccessToken } from "@/utils/auth"; +// 用于防止重复初始化的状态标记 +let isInitialized = false; + /** * 初始化WebSocket服务 */ export function setupWebSocket() { console.log("[WebSocketPlugin] 开始初始化WebSocket服务..."); + // 检查是否已经初始化 + if (isInitialized) { + console.log("[WebSocketPlugin] WebSocket服务已经初始化,跳过重复初始化"); + return; + } + + // 检查环境变量是否配置 + const wsEndpoint = import.meta.env.VITE_APP_WS_ENDPOINT; + if (!wsEndpoint) { + console.log("[WebSocketPlugin] 未配置WebSocket端点,跳过WebSocket初始化"); + return; + } + // 检查token是否存在 const token = getAccessToken(); if (!token) { @@ -29,9 +45,11 @@ export function setupWebSocket() { window.addEventListener("beforeunload", () => { console.log("[WebSocketPlugin] 窗口即将关闭,断开WebSocket连接"); dictWebSocket.closeWebSocket(); + isInitialized = false; }); console.log("[WebSocketPlugin] WebSocket服务初始化完成"); + isInitialized = true; }, 1000); // 延迟1秒初始化 } catch (error) { console.error("[WebSocketPlugin] 初始化WebSocket服务失败:", error);