Node.js+ws 库:WebSocket 心跳机制的模块化封装
·
Node.js + ws 库:WebSocket 心跳机制的模块化封装
在 WebSocket 通信中,心跳机制用于维持连接活性并检测失效连接。以下是基于 ws 库的模块化实现方案:
1. 心跳模块设计
// heartbeat.js
class Heartbeat {
/**
* @param {WebSocket} ws - WebSocket 实例
* @param {object} options - 配置项
* @param {number} options.interval - 心跳间隔(毫秒),默认 30000
* @param {number} options.timeout - 超时阈值(毫秒),默认 10000
* @param {string} options.pingMsg - 心跳请求消息,默认 'HEARTBEAT_PING'
* @param {string} options.pongMsg - 心跳响应消息,默认 'HEARTBEAT_PONG'
*/
constructor(ws, options = {}) {
this.ws = ws;
this.interval = options.interval || 30000;
this.timeout = options.timeout || 10000;
this.pingMsg = options.pingMsg || 'HEARTBEAT_PING';
this.pongMsg = options.pongMsg || 'HEARTBEAT_PONG';
this.pingTimer = null;
this.pongTimeout = null;
this.isAlive = false;
this.start();
}
start() {
this.isAlive = true;
// 监听消息响应
this.ws.on('message', (data) => {
if (data.toString() === this.pongMsg) {
this.reset();
}
});
// 启动心跳检测
this.pingTimer = setInterval(() => {
if (!this.isAlive) {
return this.terminate();
}
this.isAlive = false;
this.sendPing();
this.setPongTimeout();
}, this.interval);
}
sendPing() {
if (this.ws.readyState === this.ws.OPEN) {
this.ws.send(this.pingMsg);
}
}
setPongTimeout() {
this.pongTimeout = setTimeout(() => {
this.terminate();
}, this.timeout);
}
reset() {
this.isAlive = true;
clearTimeout(this.pongTimeout);
}
terminate() {
clearInterval(this.pingTimer);
clearTimeout(this.pongTimeout);
if (this.ws.readyState === this.ws.OPEN) {
this.ws.terminate();
}
}
}
module.exports = Heartbeat;
2. 服务端集成示例
// server.js
const WebSocket = require('ws');
const Heartbeat = require('./heartbeat');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
// 初始化心跳检测
const heartbeat = new Heartbeat(ws, {
interval: 25000,
timeout: 8000
});
// 处理业务消息
ws.on('message', (message) => {
if (message.toString() === 'HEARTBEAT_PING') {
// 响应心跳包
ws.send('HEARTBEAT_PONG');
} else {
// 处理业务数据
console.log(`Received: ${message}`);
}
});
// 连接关闭时清理
ws.on('close', () => {
heartbeat.terminate();
});
});
3. 客户端集成示例
// client.js
const WebSocket = require('ws');
const Heartbeat = require('./heartbeat');
const ws = new WebSocket('ws://localhost:8080');
ws.on('open', () => {
// 启动心跳检测
const heartbeat = new Heartbeat(ws, {
pingMsg: 'CLIENT_PING',
pongMsg: 'SERVER_PONG'
});
// 响应服务端心跳
ws.on('message', (data) => {
if (data.toString() === 'HEARTBEAT_PING') {
ws.send('HEARTBEAT_PONG');
}
});
});
4. 机制说明
-
心跳周期:
每 25 秒发送PING消息,等待 8 秒内响应 $$ T_{\text{cycle}} = \Delta t_{\text{interval}} + \Delta t_{\text{timeout}} $$ -
状态检测:
- 成功收到
PONG时重置isAlive标志 - 超时未响应时调用
terminate()关闭连接
- 成功收到
-
错误处理:
- 自动检测连接状态(
readyState === OPEN) - 清除所有定时器避免内存泄漏
- 自动检测连接状态(
5. 优化建议
- 动态调整:根据网络状况动态计算心跳间隔
- 重连机制:在
terminate()后触发重连逻辑 - 日志监控:添加调试日志记录心跳状态变化
此封装实现了:
- 心跳检测与超时处理的解耦
- 配置参数的可定制化
- 与业务逻辑的隔离
- 完整的资源清理机制
更多推荐


所有评论(0)