优化 ws切换的时候的时序差 导致遗留上次的消息
This commit is contained in:
4
env.js
4
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/',
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
// ==================== 消息发送 ====================
|
||||
|
||||
Reference in New Issue
Block a user