本地运行的WebSocket静默中断LORIOT WebSocket连接问题求助
WebSocket连接静默假死问题成因及修复方案
核心成因
- 服务端闲置超时静默断开:LORIOT平台的WebSocket服务默认设置了闲置超时规则,当连接超过指定时长没有任何双向数据交互时,服务端会直接静默销毁连接,不会发送断开帧或错误通知,因此客户端无法触发
onclose或onerror回调,连接直接进入假死状态。 - 触发服务端流控限制:LORIOT作为LoRaWAN管理平台,对单连接的消息收发频率有明确阈值限制,高频调用发送逻辑超过阈值后,服务端会直接挂起对应连接,丢弃所有后续数据但不做断开通知。
- 缺少PING/PONG心跳响应:标准WebSocket协议要求服务端定期发送PING帧校验连接活性,你当前代码没有配置PONG响应逻辑,服务端发PING帧后未收到回复,就会判定连接失效直接静默断开。
修复方案
1. 新增心跳保活与超时重连逻辑
定时向服务端发送PING帧,同时设置超时检测,超期未收到响应主动销毁旧连接并重连,参考代码如下:
var WebSocket = require('ws'); // 补充缺失的WebSocket客户端依赖引用 var WebSocketServer = require('websocket').server; var express = require('express'); var app = express(); var server = app.listen(8888); var wsServer = new WebSocketServer({ httpServer : server }); const url = 'wss://eu4pro.loriot.io/***************************' let loriotConnection = null; // 心跳配置 const HEARTBEAT_INTERVAL = 30 * 1000; // 30秒发一次心跳 const HEARTBEAT_TIMEOUT = 90 * 1000; // 90秒无响应判定为死连接 let heartbeatTimer = null; let timeoutTimer = null; // 初始化/重连连接函数 function initLoriotConnect() { loriotConnection = new WebSocket(url); loriotConnection.onopen = function(event) { console.log("Loriot WebSocket is open now."); startHeartbeat(); }; loriotConnection.onclose = function(event) { console.log("Loriot WebSocket is CLOSED now."); clearTimers(); // 延迟3秒重连 setTimeout(initLoriotConnect, 3000); }; loriotConnection.onerror = function(event) { console.log('error') } loriotConnection.onmessage = e => { // 收到任意业务消息重置超时定时器 clearTimeout(timeoutTimer); console.log(e.data) } // 收到服务端PONG响应重置超时 loriotConnection.on('pong', () => { clearTimeout(timeoutTimer); }) } function startHeartbeat() { clearTimers(); heartbeatTimer = setInterval(() => { if (loriotConnection.readyState === WebSocket.OPEN) { loriotConnection.ping(); timeoutTimer = setTimeout(() => { console.log("LORIOT连接心跳超时,主动重连"); loriotConnection.terminate(); }, HEARTBEAT_TIMEOUT); } }, HEARTBEAT_INTERVAL) } function clearTimers() { clearInterval(heartbeatTimer); clearTimeout(timeoutTimer); } // 首次初始化连接 initLoriotConnect();
2. 新增发送限流逻辑
对高频调用的发送逻辑做限流处理,根据LORIOT平台的频率限制要求,控制单秒发送请求数,溢出的请求存入缓存队列,待空闲时按速率补发。
3. 发送前校验连接状态
每次调用发送接口前,先判断loriotConnection.readyState === WebSocket.OPEN,状态异常时先缓存数据,避免向假死连接发送数据导致丢失。
内容的提问来源于stack exchange,提问作者Joe Thompson
相关产品推荐
相关产品推荐

