// let url = "ws://89.40.9.89:2109/mosty-api/mosty-websocket/socket/"; //线上 let url = "ws://155.240.22.30:2109/mosty-api/mosty-websocket/socket/"; //线上 if(process.env.NODE_ENV === 'development') { url = "ws://47.108.232.77:9537/mosty-api/mosty-websocket/socket/"; //本地 } import { getItem } from "@/utils/storage"; import emitter from "@/utils/eventBus.js"; // 导入事件总线 class WebSoketClass { constructor(props) { this.ws = null; this.state = null; this.reconnectCount = 0; this.maxReconnectCount = 10; this.reconnectInterval = 6000; this.uuid = null; // 保存UUID,用于重连时复用 this.sfzh = null; // 保存身份证号,用于重连时复用 this.fullUrl = null; // 保存完整连接URL,用于重连时复用 } static getInstance() { if (!this.instance) this.instance = new WebSoketClass(); return this.instance; } //关闭连接 static close() { if (this.instance) { this.instance.closeConnection(); } } // 关闭连接的实例方法 closeConnection() { if (this.ws) { this.ws.close(); this.ws = null; } if (this.state) { clearInterval(this.state); this.state = null; } this.reconnectCount = 0; // 重置UUID,下次连接时生成新的 this.uuid = null; this.fullUrl = null; } // 创建连接 connect(fun) { // 首次连接时获取并保存连接参数 if (!this.sfzh) { this.sfzh = getItem("idEntityCard"); } // 首次连接时生成并保存UUID if (!this.uuid) { this.uuid = this.getUUid(); } if (this.sfzh) { try { // 如果还没有完整URL或需要更新,重新构建 if (!this.fullUrl || this.maxReconnectCount == 10) { this.fullUrl = url + this.sfzh + '/' + this.uuid; this.reconnectCount = 0; } console.log('尝试连接WebSocket:', this.fullUrl); this.ws = new WebSocket(this.fullUrl); console.log(this.ws); this.ws.onopen = (e) => { console.log('WebSocket连接已打开'); // 只有在非重连状态下才重置重连计数 // 避免短暂连接成功后又关闭导致计数重置 if (this.reconnectCount === 0) { console.log('首次连接成功'); } else { console.log('重连成功'); // 重连成功后重置计数 // this.reconnectCount = 0; } this.heartCheck(); this.getMessage(); if (fun) fun(true); }; this.ws.onclose = (e) => { console.log(e); console.log('WebSocket连接已关闭,关闭码:', e.code, '原因:', e.reason); // 如果是正常关闭(1000)或手动关闭(1001),不进行重连 if (e.code !== 1000 && e.code !== 1001) { this.handleReconnect(fun); } else { console.log('WebSocket正常关闭,不进行重连'); } }; this.ws.onerror = (e) => { console.error('WebSocket连接错误:', e); this.handleReconnect(fun); }; } catch (error) { console.error('创建WebSocket连接失败:', error); this.handleReconnect(fun); } } else { console.error('获取用户身份证号失败,无法建立WebSocket连接'); if (fun) fun(false); } } // 心跳机制 heartCheck() { if (this.state) { clearInterval(this.state); } this.state = setInterval(() => { try { if (this.ws && this.ws.readyState === WebSocket.OPEN) { this.ws.send("/heart"); } else { console.log('WebSocket未连接,停止心跳'); clearInterval(this.state); this.state = null; } } catch (error) { console.error('心跳发送失败:', error); clearInterval(this.state); this.state = null; } }, 6000); } // 获取uuid getUUid() { var s = []; var hexDigits = "0123456789abcdefghijklmnopqrstuvwxyz"; for (var i = 0; i < 32; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); s[8] = s[13] = s[18] = s[23]; let uuid = s.join(""); return uuid } // 处理重连 handleReconnect(fun) { if (this.reconnectCount >= this.maxReconnectCount) { console.log('达到最大重连次数,停止重连'); if (fun) fun(false); return; } this.reconnectCount++; console.log(`尝试第${this.reconnectCount}次重连...`); setTimeout(() => { this.connect(fun); }, this.reconnectInterval); } // 接收发送消息 getMessage() { this.ws.onmessage = (e) => { console.log(e); try { if (e.data) { let newsDate = JSON.parse(e.data); // 根据消息类型发射相应的事件 if (newsDate.type === '01') { // 触发音频播放 console.log('触发音频播放'); emitter.emit('openYp', newsDate.data); // 传递消息数据 } // else if (newsDate.type === 'ALARM_STOP' || newsDate.type === 'warning_stop') { // // 触发音频停止 // emitter.emit('closeYp'); // } else if (newsDate.type === 'POSITION_UPDATE') { // // 位置更新事件 // emitter.emit('positionUpdate', newsDate.data); // } else if (newsDate.type === 'STATUS_UPDATE') { // // 状态更新事件 // emitter.emit('statusUpdate', newsDate.data); // } // // 通用消息事件 // emitter.emit('webSocketMessage', newsDate); } } catch (error) { console.error('处理WebSocket消息失败:', error); // 如果是心跳响应,不报错 if (e.data !== '/heart') { console.error('消息内容:', e.data); } } }; } } export default WebSoketClass;