websocket默认无心跳机制,需手动实现ping/pong保活:服务端周期发送ping帧、监听pong事件判断存活;客户端亦可发送自定义ping消息,服务端手动回复pong;推荐间隔20–45秒,宽限期5–15秒。

WebSocket 默认没有内置心跳机制,但网络中间设备(如代理、NAT、防火墙)常因长时间无数据传输而主动关闭空闲连接。通过手动实现 Ping/Pong 心跳,能有效维持连接活跃,避免意外断连。
服务端主动发送 Ping,客户端响应 Pong
这是最常见且推荐的方式:由服务端周期性发送 ping 帧,客户端收到后必须立即回一个 pong 帧(浏览器自动处理,无需手动调用)。服务端可通过监听 pong 事件判断客户端是否存活。
- Node.js(ws 库)示例:
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
// 每 30 秒发一次 ping
const pingInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping(); // 发送 ping 帧
}
}, 30000);
// 收到客户端 pong 后重置超时计时器
let pongTimeout;
const resetPongTimeout = () => {
if (pongTimeout) clearTimeout(pongTimeout);
pongTimeout = setTimeout(() => {
ws.terminate(); // 超时未收到 pong,强制断开
}, 10000); // 等待 pong 的宽限期
};
resetPongTimeout();
ws.on('pong', resetPongTimeout);
ws.on('close', () => clearInterval(pingInterval));
});
客户端定时发送 Ping(需服务端配合响应)
部分场景下客户端更可控(如弱网设备需主动保活),可由客户端定时调用 ws.send() 发送自定义心跳消息(如 {"type":"ping"}),服务端收到后回复 {"type":"pong"}。注意:这不是标准 Ping/Pong 帧,不触发浏览器自动 pong 行为,需完全手动实现。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 客户端 JS 示例:
const ws = new WebSocket('ws://example.com');
let heartbeatTimer;
const startHeartbeat = () => {
heartbeatTimer = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ping', ts: Date.now() }));
}
}, 25000);
};
ws.onopen = () => startHeartbeat();
ws.onmessage = (e) => {
const data = JSON.parse(e.data);
if (data.type === 'pong') {
console.log('Heartbeat OK');
}
};
ws.onclose = () => clearInterval(heartbeatTimer);
关键参数设置建议
心跳间隔和超时时间需权衡稳定性与资源消耗:
- 服务端 ping 间隔建议 20–45 秒;客户端自定义心跳建议 25–35 秒(避开多数 NAT 超时阈值,通常为 30–60 秒)
- Pong 响应宽限期(即等待 pong 的超时)设为 5–15 秒,确保有足够缓冲应对短暂延迟
- 避免过短间隔(如
- 在
onopen启动心跳,在onclose/onerror清理定时器,防止内存泄漏
补充:浏览器自动处理与限制
现代浏览器对 WebSocket 的 ping/pong 帧有底层支持:调用 ws.ping()(若 API 支持)或收到服务端 ping 时,会自动回复 pong,开发者无需干预。但注意:
-
浏览器不提供 public 的
ws.ping()方法 —— 标准 WebSocket API 没有暴露发送 ping 的接口,只能依赖服务端发起 - 所以客户端“主动 ping”只能走应用层协议(如发 JSON 消息),服务端需识别并回应
- 所有心跳逻辑都应在连接打开后启动,并在连接关闭时及时清理定时器
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










