142 lines
3.7 KiB
TypeScript
142 lines
3.7 KiB
TypeScript
import { useDictSync } from "@/composables";
|
||
import { AuthStorage } from "@/utils/auth";
|
||
|
||
/**
|
||
* WebSocket 服务实例约定接口
|
||
* 至少包含 disconnect/closeWebSocket/cleanup 三者之一
|
||
*/
|
||
type WebSocketService = {
|
||
disconnect?: () => void;
|
||
closeWebSocket?: () => void;
|
||
cleanup?: () => void;
|
||
[key: string]: any;
|
||
};
|
||
|
||
// 全局 WebSocket 实例管理
|
||
const websocketInstances = new Map<string, WebSocketService>();
|
||
|
||
// 用于防止重复初始化的状态标记
|
||
let isInitialized = false;
|
||
let dictWebSocketInstance: ReturnType<typeof useDictSync> | null = null;
|
||
|
||
/**
|
||
* 注册 WebSocket 实例,便于统一清理
|
||
*/
|
||
export function registerWebSocketInstance(key: string, instance: WebSocketService) {
|
||
websocketInstances.set(key, instance);
|
||
}
|
||
|
||
/**
|
||
* 获取 WebSocket 实例
|
||
*/
|
||
export function getWebSocketInstance(key: string) {
|
||
return websocketInstances.get(key);
|
||
}
|
||
|
||
/**
|
||
* 初始化WebSocket服务
|
||
*/
|
||
export function setupWebSocket() {
|
||
// 检查是否已经初始化
|
||
if (isInitialized) {
|
||
return;
|
||
}
|
||
|
||
// 检查环境变量是否配置
|
||
const wsEndpoint = import.meta.env.VITE_APP_WS_ENDPOINT;
|
||
if (!wsEndpoint) {
|
||
console.log("[WebSocketPlugin] 未配置WebSocket端点,跳过WebSocket初始化");
|
||
return;
|
||
}
|
||
|
||
// 检查是否已登录(基于是否存在访问令牌)
|
||
if (!AuthStorage.getAccessToken()) {
|
||
console.warn(
|
||
"[WebSocketPlugin] 未找到访问令牌,WebSocket初始化已跳过。用户登录后将自动重新连接。"
|
||
);
|
||
return;
|
||
}
|
||
|
||
try {
|
||
// 延迟初始化,确保应用完全启动
|
||
setTimeout(() => {
|
||
// 保存实例引用
|
||
dictWebSocketInstance = useDictSync();
|
||
registerWebSocketInstance("dictSync", dictWebSocketInstance);
|
||
|
||
// 初始化字典WebSocket服务
|
||
dictWebSocketInstance.initWebSocket();
|
||
// 初始化在线用户计数WebSocket
|
||
import("@/composables").then(({ useOnlineCount }) => {
|
||
const onlineCountInstance = useOnlineCount({ autoInit: false });
|
||
onlineCountInstance.initWebSocket();
|
||
});
|
||
|
||
// 在窗口关闭前断开WebSocket连接
|
||
window.addEventListener("beforeunload", handleWindowClose);
|
||
isInitialized = true;
|
||
}, 1000); // 延迟1秒初始化
|
||
} catch (error) {
|
||
console.error("[WebSocketPlugin] 初始化WebSocket服务失败:", error);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理窗口关闭
|
||
*/
|
||
function handleWindowClose() {
|
||
cleanupWebSocket();
|
||
}
|
||
|
||
/**
|
||
* 清理WebSocket连接
|
||
*/
|
||
export function cleanupWebSocket() {
|
||
// 清理字典 WebSocket
|
||
if (dictWebSocketInstance) {
|
||
try {
|
||
dictWebSocketInstance.closeWebSocket();
|
||
} catch (error) {
|
||
console.error("[WebSocketPlugin] 断开字典WebSocket连接失败:", error);
|
||
}
|
||
}
|
||
|
||
// 清理所有注册的 WebSocket 实例
|
||
websocketInstances.forEach((instance, key) => {
|
||
try {
|
||
if (instance && typeof instance.disconnect === "function") {
|
||
instance.disconnect();
|
||
} else if (instance && typeof instance.closeWebSocket === "function") {
|
||
instance.closeWebSocket();
|
||
} else if (instance && typeof instance.cleanup === "function") {
|
||
instance.cleanup();
|
||
}
|
||
} catch (error) {
|
||
console.error(`[WebSocketPlugin] 断开 ${key} WebSocket连接失败:`, error);
|
||
}
|
||
});
|
||
|
||
// 清空实例映射
|
||
websocketInstances.clear();
|
||
|
||
// 移除事件监听器
|
||
window.removeEventListener("beforeunload", handleWindowClose);
|
||
|
||
// 重置状态
|
||
dictWebSocketInstance = null;
|
||
isInitialized = false;
|
||
}
|
||
|
||
/**
|
||
* 重新初始化WebSocket(用于登录后重连)
|
||
*/
|
||
export function reinitializeWebSocket() {
|
||
// 先清理现有连接
|
||
cleanupWebSocket();
|
||
|
||
// 延迟后重新初始化
|
||
setTimeout(() => {
|
||
setupWebSocket();
|
||
}, 500);
|
||
}
|