WebSocket初始化遇设备离线:setInterval触发异常致浏览器崩溃求助
WebSocket重连定时器异常问题修复
问题根源
你遇到的浏览器崩溃问题,核心原因是定时器调用方式错误:在setInterval和setTimeout中,你直接执行了initWebSocket(event),而不是传入函数引用。这会导致initWebSocket立刻被执行,而非等待指定的30秒,进而触发onerror无限循环,瞬间耗尽浏览器资源。
修复方案
将定时器的回调改为匿名函数,确保只有定时器触发时才执行重连逻辑;同时统一定时器清理逻辑,避免重复创建定时器:
var websocket1; var websocket2; var websocket3; var sockTimer_1 = null; var sockTimer_2 = null; var sockTimer_3 = null; const wsRetry = 30; // 重连间隔(秒) function initWebSocket(whichSocket) { console.log(`Trying to open a WebSocket connection ${whichSocket}...`); if (whichSocket === 1) { websocket1 = new WebSocket(gateway1); websocket1.onopen = () => onOpen(1); websocket1.onerror = () => onError(1); websocket1.onclose = () => onClose(1); websocket1.onmessage = onMessage_1; } else if (whichSocket === 2) { websocket2 = new WebSocket(gateway2); websocket2.onopen = () => onOpen(2); websocket2.onerror = () => onError(2); websocket2.onclose = () => onClose(2); websocket2.onmessage = onMessage_2; } else if (whichSocket === 3) { websocket3 = new WebSocket(gateway3); websocket3.onopen = () => onOpen(3); websocket3.onerror = () => onError(3); websocket3.onclose = () => onClose(3); websocket3.onmessage = onMessage_3; } } function onOpen(event) { // 连接成功后清理对应定时器 if (event === 1) { clearTimeout(sockTimer_1); sockTimer_1 = null; } else if (event === 2) { clearTimeout(sockTimer_2); sockTimer_2 = null; } else if (event === 3) { clearTimeout(sockTimer_3); sockTimer_3 = null; } console.log(`Connection opened: ${event}`); } function onError(event) { console.log(`Connection error - trying again: ${event}`); // 先清理已有定时器,避免重复 if (event === 1) { if (sockTimer_1) { clearTimeout(sockTimer_1); } // 用匿名函数包裹,确保30秒后才执行重连 sockTimer_1 = setTimeout(() => initWebSocket(event), wsRetry * 1000); } else if (event === 2) { if (sockTimer_2) { clearTimeout(sockTimer_2); } sockTimer_2 = setTimeout(() => initWebSocket(event), wsRetry * 1000); } else if (event === 3) { if (sockTimer_3) { clearTimeout(sockTimer_3); } sockTimer_3 = setTimeout(() => initWebSocket(event), wsRetry * 1000); } } function onClose(event) { console.log(`Connection closed - reconnecting: ${event}`); if (event === 3) { if (sockTimer_3) { clearTimeout(sockTimer_3); } sockTimer_3 = setTimeout(() => initWebSocket(event), wsRetry * 1000); } // 可以补充其他socket的关闭重连逻辑 }
关键修改点
- 将
setInterval替换为setTimeout:单次重连更合理,避免多次叠加定时器;如果需要持续重连,可以在initWebSocket失败后再次设置setTimeout - 用
() => initWebSocket(event)匿名函数作为定时器回调,确保函数不会立即执行 - 每次设置新定时器前,先清理旧定时器并置为null,避免内存泄漏和重复触发
- 统一使用
===进行严格相等判断,避免隐式类型转换问题
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

