// WebSocketService.js class WebSocketService { constructor() { this.websocket = null; this.heartbeatTimer = null; this.reconnectTimer = null; this.token = null; } initWebSocket(token) { if (!token) { console.warn('❌ WebSocket token 为空'); // 全局提示用户登录过期 if (typeof window !== 'undefined' && window.Vue && Vue.prototype.$message) { Vue.prototype.$message.error('登录状态已过期,请重新登录!'); } else { alert('登录状态已过期,请重新登录!'); } // 退出并跳转登录页 if (this.store) { this.store.dispatch("LogOut").then(() => { location.href = "/index"; }); } else { // 如果没有 store 引用,直接跳转 location.href = "/index"; } return; } // 如果已连接或连接中,跳过 if (this.websocket && (this.websocket.readyState === WebSocket.OPEN || this.websocket.readyState === WebSocket.CONNECTING)) { console.log('ℹ️ WebSocket 已连接或连接中,跳过重复连接'); return; } this.token = token; const wsUrl = `${process.env.VUE_APP_WS_URL}/${token}`; console.log("🔌 WebSocket连接中:", wsUrl); this.websocket = new WebSocket(wsUrl); this.websocket.onopen = this.websocketonopen.bind(this); this.websocket.onerror = this.websocketonerror.bind(this); this.websocket.onmessage = this.setOnmessageMessage.bind(this); this.websocket.onclose = this.websocketclose.bind(this); // 初始化状态为 connecting window.dispatchEvent(new CustomEvent('ws-status', { detail: 'connecting' })); } websocketonopen() { console.log('✅ WebSocket连接成功'); this.startHeartbeat(); window.dispatchEvent(new CustomEvent('ws-status', { detail: 'open' })); } websocketonerror(e) { console.error('❌ WebSocket连接错误:', e); window.dispatchEvent(new CustomEvent('ws-status', { detail: 'error' })); this.reconnect(); } websocketclose(e) { console.warn('⚠️ WebSocket连接关闭:', e); this.stopHeartbeat(); window.dispatchEvent(new CustomEvent('ws-status', { detail: 'closed' })); this.reconnect(); } reconnect() { if (this.reconnectTimer) return; if (this.websocket && (this.websocket.readyState === WebSocket.OPEN || this.websocket.readyState === WebSocket.CONNECTING)) { console.log('ℹ️ WebSocket 已连接,无需重连'); return; } this.reconnectTimer = setTimeout(() => { console.warn('🔁 尝试重新连接 WebSocket...'); this.initWebSocket(this.token); this.reconnectTimer = null; }, 5000); } setOnmessageMessage(event) { try { const msg = JSON.parse(event.data); console.log("📩 收到消息:", msg); if (msg.type) { window.dispatchEvent(new CustomEvent(msg.type, { detail: msg })); } } catch (err) { console.error("WebSocket消息解析失败:", err); } } startHeartbeat() { this.stopHeartbeat(); this.heartbeatTimer = setInterval(() => { if (this.websocket && this.websocket.readyState === WebSocket.OPEN) { this.websocket.send(JSON.stringify({ type: 'heartbeat', time: new Date().toISOString() })); } }, 30000); } stopHeartbeat() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; } } destroy() { this.stopHeartbeat(); if (this.websocket) { this.websocket.close(); this.websocket = null; } console.log("🧹 WebSocket 已销毁"); window.dispatchEvent(new CustomEvent('ws-status', { detail: 'closed' })); } } export default new WebSocketService();