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