import emitter from '@/utils/mitt'; type WebSocketInternalOptions = { fullUrl: string; reconnectInterval?: number; }; let websocket: WebSocket | null = null; let reconnectTimer: any = null; let isManualClose = false; /** 初始化WebSocket */ export function initWebSocket(options: WebSocketInternalOptions) { const { fullUrl, reconnectInterval = 3000 } = options; // 关闭已有连接 if (websocket) { websocket.close(); } if (!('WebSocket' in window)) { console.error('当前浏览器不支持WebSocket'); return; } try { websocket = new WebSocket(fullUrl); // 连接成功 websocket.onopen = () => { clearTimeout(reconnectTimer!); isManualClose = false; console.log('WebSocket 连接成功'); }; // 接收消息,自动解析按 msgType 分发事件 websocket.onmessage = (event) => { try { const rawMsg = JSON.parse(event.data); const msgType = rawMsg.msgType; emitter.emit(msgType, rawMsg); } catch (err) { console.error('WebSocket消息解析失败:', err); } }; // 连接异常 websocket.onerror = (error) => { console.error('WebSocket 连接异常:', error); startReconnect(() => initWebSocket(options), reconnectInterval); }; // 连接关闭 websocket.onclose = () => { console.log('WebSocket 连接关闭'); if (!isManualClose) { startReconnect(() => initWebSocket(options), reconnectInterval); } }; } catch (error) { console.error('WebSocket 创建失败:', error); startReconnect(() => initWebSocket(options), reconnectInterval); } } /** 发送ws消息 */ export function sendWebSocketMessage(message: any): boolean { if (websocket && websocket.readyState === WebSocket.OPEN) { websocket.send(JSON.stringify(message)); return true; } console.error('WebSocket未连接,发送失败'); return false; } /** 手动关闭ws(登出时调用) */ export function closeWebSocket(): void { isManualClose = true; if (reconnectTimer) { clearTimeout(reconnectTimer); } websocket?.close(); websocket = null; } /** 获取当前连接状态 */ export function getWebSocketState(): number | null { return websocket?.readyState || null; } // 内部重连私有方法 function startReconnect(connectCallback: () => void, interval: number): void { if (reconnectTimer) { clearTimeout(reconnectTimer); } reconnectTimer = setTimeout(connectCallback, interval); }