websocket心跳需“发前验状态、发后等响应、断时清定时器”:每30秒发ping前检查readystate为open,同时启5秒pong超时检测,收pong即清除超时定时器,超时则close并重连;onclose/onerror中清除所有定时器,onopen后重建。

WebSocket 连接需要心跳机制来维持活跃状态、及时发现断连并触发重连。单纯用 setInterval 发送心跳包容易出问题——比如发送失败未清理定时器、网络恢复后重复启动、或心跳响应超时未处理。关键不是“怎么发”,而是“怎么发得稳”。
用独立定时器 + 响应确认机制
避免只靠发送定时器,要搭配服务端响应确认。客户端发心跳(如 {"type":"ping"}),服务端必须回 {"type":"pong"}。客户端收到后重置超时检测逻辑:
- 启动一个「发送定时器」,每 30 秒调用
ws.send(ping) - 同时启动一个「响应超时定时器」(如 5 秒),一旦收到
pong就clearTimeout - 若超时未收到 pong,视为连接异常,主动
ws.close()并触发重连
发送前检查连接状态
不能无脑发 ping。每次定时触发前,必须判断 ws.readyState === WebSocket.OPEN:
- 如果为
CLOSING或CLOSED,直接清除定时器,不发包 - 如果为
CONNECTING(重连中),跳过本次,等onopen后再启动定时器 - 避免向正在关闭或未建立的连接发数据,防止报错或资源浪费
重连时重置所有定时器
断连重试过程中,旧的定时器可能还在运行,造成多个心跳并发、重复发包甚至内存泄漏:
- 在
onclose和onerror中,统一调用clearInterval(pingTimer)和clearTimeout(pongTimeout) - 在新连接成功(
onopen)后再重新初始化两个定时器 - 建议把定时器 ID 存在实例属性上(如
this.pingTimer),方便管理
服务端配合不可少
客户端心跳只是半边腿。服务端必须:
- 收到
ping后立即返回pong(不要排队或延迟) - 自己也维护连接存活时间,对长时间没收到任何消息(包括 ping)的连接主动断开
- 避免依赖客户端单方面心跳,双向保活更可靠
不复杂但容易忽略。核心就三点:发之前看状态、发完等回应、断了清干净。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











