diff --git a/env.js b/env.js index 585e162..a14bf14 100644 --- a/env.js +++ b/env.js @@ -15,8 +15,8 @@ const envConfig = { //mqtt_url: "ws://1.95.137.212:8083/mqtt", //geoserver_url: "http://192.168.2.59:7000/geoserver" - //baseURL: 'http://1.95.137.212:8081',//http://192.168.2.56:8081 - baseURL: 'http://192.168.2.34:8081',//http://192.168.2.56:8081 + baseURL: 'http://1.95.137.212:8081',//http://192.168.2.56:8081 + //baseURL: 'http://192.168.2.34:8081',//http://192.168.2.56:8081 //baseURL: 'https://serviceri.satabot.com', //WS_URL: 'ws://1.95.137.212:9002/ws/', WS_URL: 'ws://192.168.2.34:9002/ws/', diff --git a/src/components/WebSocketManager.ts b/src/components/WebSocketManager.ts index 988d62d..9358164 100644 --- a/src/components/WebSocketManager.ts +++ b/src/components/WebSocketManager.ts @@ -61,44 +61,50 @@ class WebSocketManager { // ==================== 连接管理 ==================== public connect(serialNumber: string, wsUrl: string): void { - console.log("创建开始");//ws://192.168.2.56:9002/ws/ - // 清除之前的重连计时器 + console.log("创建开始"); + + // 清除重连计时器 if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; } + if (serialNumber == null || serialNumber.trim() === "") { + console.log("serialNumber 是空/空白,停止执行"); + return; + } + // 如果序列号相同且已连接,跳过 if (this.ws && this.currentSerialRef === serialNumber && this.status === 'connected') { console.log('WebSocket already connected for this device'); return; } - // 如果序列号不同,先关闭旧连接 - if (this.ws && this.currentSerialRef !== serialNumber) { + // ========== 重点修复:关闭旧连接,并且清空旧ws的事件监听,防止旧消息回调执行 ========== + if (this.ws) { + // 解绑所有事件,阻止旧ws继续触发onmessage/onclose + this.ws.onopen = null; + this.ws.onmessage = null; + this.ws.onerror = null; + this.ws.onclose = null; this.close(); + this.ws = null; } this.currentSerialRef = serialNumber; this.setStatus('connecting'); this.isManualCloseRef = false; + // 提前赋值,不要等到new WebSocket之后 + this.wsSerialRef = serialNumber; console.log('Connecting WebSocket for', serialNumber); - - if (serialNumber == null || serialNumber.trim() === "") { - console.log("serialNumber 是空/空白,停止执行"); - return; - } - this.ws = new WebSocket(wsUrl); - this.wsSerialRef = serialNumber; this.ws.onopen = () => { console.log('WebSocket Connected'); this.setStatus('connected'); - const dataStr = localStorage.getItem('userInfo'); if (!dataStr) { console.error('用户信息未找到,无法发送认证包'); @@ -109,18 +115,21 @@ class WebSocketManager { console.log('WebSocket%', token); console.log('WebSocket%', parse); - console.log("开始发送认证包");//ws://192.168.2.56:9002/ws/ - // 发送 AUTH 认证消息 + console.log("开始发送认证包"); this.send({ type: 'AUTH', token: token, userName: parse.username, deviceId: serialNumber, }); - }; this.ws.onmessage = (event) => { + // 【防御二次校验】只有当前活跃serial才处理消息,旧连接残留消息直接丢弃 + if (this.wsSerialRef !== this.currentSerialRef) { + console.log('丢弃过期ws消息'); + return; + } try { const data = JSON.parse(event.data); this.handleMessage(data); @@ -137,7 +146,7 @@ class WebSocketManager { const { code, reason, wasClean } = event; console.log('[WebSocket closed]', 'code =', code, 'reason =', reason || '(no reason)', 'wasClean =', wasClean); - // 如果不是当前设备的 ws,忽略 + // 不是当前设备直接忽略 if (this.wsSerialRef !== this.currentSerialRef) { console.log('🟡 ignore old ws close'); return; @@ -146,15 +155,13 @@ class WebSocketManager { this.ws = null; this.setStatus('disconnected'); - // 主动关闭不重连 if (this.isManualCloseRef || !this.currentSerialRef) { return; } - // 5 秒后自动重连 this.reconnectTimer = setTimeout(() => { if (this.currentSerialRef === this.wsSerialRef) { - this.connect(this.currentSerialRef, wsUrl); + this.connect(this.currentSerialRef!, wsUrl); } }, 5000); }; @@ -164,21 +171,17 @@ class WebSocketManager { public close(): void { this.isManualCloseRef = true; - if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; } - if (this.ws) { - console.log('Closing WebSocket'); - this.ws.close(); - this.ws = null; + try { + this.ws.close(1000, 'manual close'); + } catch (e) { + console.warn('ws close exception', e); + } } - - this.currentSerialRef = null; - this.wsSerialRef = null; - this.setStatus('disconnected'); } // ==================== 消息发送 ====================