1. 客户端定时发送心跳,服务端回应
最简单直白的方案。客户端定时发一个心跳消息,服务端收到后回个信号,双方确认连接活着。
js
// 客户端
setInterval(() => {
socket.emit('heartbeat', { time: Date.now() });
}, 10000);
socket.on('heartbeat_ack', () => {
console.log('收到服务端心跳回复');
});
js
// 服务端
io.on('connection', socket => {
socket.on('heartbeat', () => {
socket.emit('heartbeat_ack');
});
// 这里需要自己写超时断开逻辑
});
优点 :简单,易于实现
缺点:服务端必须自己写超时检测逻辑,容易遗漏
2. 双向 ping-pong 心跳
双方互相发"ping",收到后回"pong",确认彼此在线,健壮性更高。
js
// 客户端
setInterval(() => socket.emit('ping'), 10000);
socket.on('pong', () => {
console.log('收到服务端pong');
});
socket.on('ping', () => socket.emit('pong'));
js
// 服务端
const pingInterval = setInterval(() => socket.emit('ping'), 10000);
socket.on('pong', () => console.log('收到客户端pong'));
socket.on('ping', () => socket.emit('pong'));
socket.on('disconnect', () => clearInterval(pingInterval));
优点 :双向确认,连接更可靠
缺点:消息量增加,实现复杂度稍高
3. 心跳携带业务状态
心跳消息不仅是"你还活着",还带上业务相关的数据,减少额外请求。
js
setInterval(() => {
socket.emit('heartbeat', {
status: 'active',
task: 'uploading',
timestamp: Date.now()
});
}, 15000);
优点 :一箭双雕,减少请求次数
缺点:消息体积变大,处理逻辑更复杂
4. 超时检测与断线重连
心跳发出后,启动超时计时器,没收到回应则断线重连。
js
let heartbeatTimeout;
function sendHeartbeat() {
socket.emit('heartbeat');
heartbeatTimeout = setTimeout(() => {
console.log('心跳超时,开始重连');
socket.disconnect();
socket.connect();
}, 5000);
}
setInterval(sendHeartbeat, 10000);
socket.on('heartbeat_ack', () => {
clearTimeout(heartbeatTimeout);
});
优点 :自动重连,提升体验
缺点:需要调试断线重连策略
5.socket.io 的内置心跳机制
Socket.IO 是一个库,可以在客户端和服务器之间实现 低延迟 , 双向 和 基于事件的 通信。
- 安装
js
npm install socket.io-client
- 使用
js
import { io } from 'socket.io-client';
// 连接到服务器
const socket = io('http://localhost:3000');
socket.on('connect', () => {
console.log('连接成功,客户端ID:', socket.id);
});
socket.on('message', data => {
console.log('收到消息:', data);
});
// 发送消息给服务器
socket.emit('message', 'Hello from browser');
客户端不用写任何心跳相关代码,socket.io自动搞定。你甚至可以监听
ping
和pong
事件,用于调试:
js
socket.on('ping', () => console.log('收到ping'));
socket.on('pong', latency => console.log('收到pong,延迟:', latency, 'ms'));
总结
方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
客户端单向心跳 | 简单,易实现 | 需服务端超时检测 | 只关注客户端活跃性 |
双向 ping-pong | 双向确认,健壮 | 实现稍复杂,消息多 | 双向通信,高可靠需求 |
携带业务数据心跳 | 节省额外请求 | 消息体积大,逻辑复杂 | 业务状态实时更新 |
超时检测+重连 | 自动重连,提升体验 | 需要调试断线重连策略 | 高可用系统 |
socket.io 内置心跳 | 免维护,自动且稳定 | 灵活度有限,依赖框架 | socket.io项目首选 |