WebSocket心跳重连需手动实现:用业务层“ping/pong”心跳包检测连接(15–30秒间隔,5–10秒超时),配合指数退避重连(如1/2/4/8秒,上限5次)、多事件监听(onerror/onclose/beforeunload)、重连后重绑事件、离线缓存+msgId幂等重发保障消息可靠。

WebSocket 心跳重连不是浏览器自动提供的功能,需要手动实现:用定时心跳检测连接状态,配合错误监听和重连策略来维持长连接。
心跳检测:发 ping、收 pong
WebSocket 协议本身支持 ping/pong 帧,但浏览器 API **不暴露发送 ping 的接口**,所以通常用业务层“心跳包”代替:客户端定期 send 一个简单消息(如 "ping"),服务端收到后立即回一个 "pong"。客户端用 setTimeout 设置超时,若规定时间内没收到 pong,就认为连接异常。
- 心跳间隔建议 15–30 秒,超时设为 5–10 秒(避免误判)
- 心跳 timer 应在
onopen后启动,onclose或onerror时清除 - 不要依赖
ws.readyState === WebSocket.OPEN判断是否可用——它可能还是OPEN,但实际已断连(如中间网络中断)
重连策略:指数退避 + 最大尝试次数
断连后立刻重试容易打爆服务端或触发限流。推荐使用带退避的重连:
- 首次重连延迟 1 秒,失败后下一次延迟 2 秒,再失败则 4 秒、8 秒……即
delay = Math.min(base * 2^retryCount, maxDelay) - 设置最大重试次数(如 5 次),超过后停止并通知用户
- 每次重连前检查是否已手动关闭(如页面卸载、用户点击断开),避免无效重连
- 重连过程中可禁用发送功能,或把待发消息暂存到队列,重连成功后再 flush
关键事件监听与清理
仅监听 onclose 不够——网络闪断可能只触发 onerror,甚至静默断连。需组合监听:
立即学习“Java免费学习笔记(深入)”;
-
onerror:捕获底层错误(如 DNS 失败、SSL 握手失败),一般立即触发重连 -
onclose:区分event.code,如1006(异常关闭)、1001(主动关闭),只对非主动关闭码重连 -
beforeunload/visibilitychange:页面切后台或关闭时,主动ws.close()并清除心跳 timer,防止内存泄漏 - 重连新建 WebSocket 实例后,务必重新绑定
onmessage、onopen等 handler,旧实例的监听器不会自动迁移
发送可靠性:离线缓存 + 重发确认
心跳和重连解决“连得上”,但不保证消息必达。对重要操作(如下单、提交表单),需额外保障:
- 发送消息前生成唯一
msgId,服务端处理完返回{ ack: msgId } - 客户端维护待确认队列,超时未 ack 则重发(最多 2–3 次)
- 页面离线时(
navigator.onLine === false或心跳连续失败),把消息存入localStorage或IndexedDB,恢复连接后逐条重发 - 服务端需幂等设计,同一
msgId多次到达只处理一次


















