WebSocket心跳机制用于检测连接的活跃状态,防止连接因网络问题或超时而断开。
为什么需要心跳
- 检测连接状态:及时发现连接是否断开
- 保持连接活跃:防止中间设备(如防火墙、NAT)因长时间无数据传输而关闭连接
- 快速故障恢复:连接断开后可以快速重连
心跳实现方式
客户端发起心跳
javascript// 客户端定时发送心跳 const ws = new WebSocket('ws://example.com'); let heartbeatInterval; function startHeartbeat() { heartbeatInterval = setInterval(() => { if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ type: 'ping' })); } }, 30000); // 每30秒发送一次 } function stopHeartbeat() { clearInterval(heartbeatInterval); } ws.onopen = startHeartbeat; ws.onclose = stopHeartbeat;
服务器响应心跳
javascript// 服务器端处理心跳 wss.on('connection', (ws) => { ws.on('message', (message) => { const data = JSON.parse(message); if (data.type === 'ping') { ws.send(JSON.stringify({ type: 'pong' })); } }); });
心跳间隔设置
- 推荐间隔:30-60秒
- 过短:增加服务器负担和网络流量
- 过长:无法及时检测到连接断开
超时处理
javascriptlet pongTimeout; const TIMEOUT = 5000; // 5秒超时 function sendPing() { ws.send(JSON.stringify({ type: 'ping' })); pongTimeout = setTimeout(() => { console.log('心跳超时,连接可能已断开'); ws.close(); }, TIMEOUT); } ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'pong') { clearTimeout(pongTimeout); } };
最佳实践
- 双向心跳:客户端和服务器都可以发起心跳
- 动态调整:根据网络状况动态调整心跳间隔
- 指数退避:重连时使用指数退避策略
- 状态监控:记录心跳成功/失败次数,用于监控连接质量