WebSocket 心跳机制
WebSocket 心跳用于保持连接和检测服务端状态
问题
WebSocket 中的心跳机制是为了解决什么问题?
解答
WebSocket 心跳机制主要解决两个问题:
1. 保持连接不被断开
服务端通常会设置连接超时时间,如果长时间没有数据传输,连接会被自动断开。通过定时发送心跳消息,可以让服务端知道连接仍然活跃,避免超时断线。
// 客户端心跳实现
let heartbeatTimer = null;
function startHeartbeat(ws) {
heartbeatTimer = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }));
}
}, 30000); // 每 30 秒发送一次
}
function stopHeartbeat() {
if (heartbeatTimer) {
clearInterval(heartbeatTimer);
heartbeatTimer = null;
}
}
2. 检测服务端是否正常
心跳不仅是单向发送,还需要服务端响应。如果发送心跳后,服务端在规定时间内没有响应,说明连接可能已经断开或服务端异常,此时需要进行重连。
let ws = null;
let heartbeatTimer = null;
let heartbeatTimeout = null;
function connect() {
ws = new WebSocket('ws://example.com');
ws.onopen = () => {
startHeartbeat();
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
// 收到心跳响应,重置超时计时器
if (data.type === 'pong') {
clearTimeout(heartbeatTimeout);
}
};
ws.onclose = () => {
stopHeartbeat();
// 3 秒后重连
setTimeout(connect, 3000);
};
}
function startHeartbeat() {
heartbeatTimer = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping' }));
// 设置超时检测,5 秒内未收到响应则认为连接异常
heartbeatTimeout = setTimeout(() => {
ws.close();
}, 5000);
}
}, 30000);
}
function stopHeartbeat() {
clearInterval(heartbeatTimer);
clearTimeout(heartbeatTimeout);
}
关键点
- 定时发送心跳消息,防止连接因超时被服务端断开
- 心跳需要服务端响应,用于检测服务端是否正常工作
- 如果心跳响应超时,应主动关闭连接并重连
- 心跳间隔通常设置为 30 秒左右,响应超时设置为 5 秒左右
目录