高性能websocket自动重连需用状态机管理生命周期、指数退避+抖动重试、主动心跳探测三者协同:状态机定义connecting/open/closing/closed/reconnecting五态并更新this.status;重试延迟=2^retry×1000ms(上限30s)叠加±15%抖动,最多12次;心跳每20秒发ping,超10秒未收pong则close强制重连;每次重连前硬清理ws实例、定时器及监听器,并缓存send消息待open后重发。

要用 class 封装高性能 WebSocket 自动重连,核心不是“多写几个方法”,而是用状态机管住生命周期、用退避策略压住重试风暴、用心跳兜住静默断连——三者缺一不可。
状态机必须独立管理连接阶段
别依赖 readyState 做唯一判断,它滞后且不可靠。你需要自己定义清晰的内部状态:
- CONNECTING:正在发起连接,禁止 send、暂停心跳
- OPEN:可收发消息,启动心跳定时器
- CLOSING:收到 close 指令或主动关闭中,禁止新消息入队
- CLOSED:连接彻底断开,清理资源后进入重连准备
- RECONNECTING:退避中,屏蔽重复触发,防止雪崩
每次状态变更都应更新一个 this.status 字段,并配合布尔标志(如 isReconnecting)拦截无效调用。
重连必须带指数退避 + 抖动 + 上限
固定延迟重试在弱网下极易失败,也容易触发服务端限流。推荐公式:
- 基础延迟 =
Math.min(2 ** retryCount * 1000, 30000) - 加抖动 =
delay * (0.85 + Math.random() * 0.3)(±15%) - 最大重试次数建议 ≤12 次,总耗时控制在 90 秒内
超过上限后可降级为轮询或提示用户手动重连,避免无意义空转。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
心跳要主动探测 + 超时兜底 + 服务端协同
仅靠 setInterval 发 ping 不够,必须配超时判定:
- 客户端每 20 秒发
{"type":"ping","ts":Date.now()} - 每次发 ping 前
clearTimeout(this.heartbeatTimeout) - 收到
{"type":"pong"}后重置超时计时器(建议 timeout = 10s) - 连续 2 次未 pong,主动
ws.close(4999, "no_pong"),强制走 onclose 流程
注意:心跳逻辑必须绑定到当前 ws 实例,每次重连后重建,不能复用旧定时器。
资源清理和消息缓存是稳定关键
每次重连前必须做“硬清理”:
- 显式设
this.ws = null,防止复用残留实例 -
clearInterval(this.pingInterval)、clearTimeout(this.heartbeatTimeout) - 移除旧 ws 的所有监听器(推荐具名函数 +
removeEventListener)
业务层 send() 应自动入队:this.sendQueue.push(data);重连成功且状态为 OPEN 后,再批量重发。










