WebSocket断线重连与离线消息队列需手动实现:监听onclose/onerror事件,用指数退避(100ms起翻倍,上限5–10秒)和最大重试次数(如10次)自动重连;连接恢复后按FIFO顺序重发内存队列中带唯一ID、超时重试(最多3次)的未确认消息;服务端需幂等去重,客户端可选IndexedDB持久化关键消息并设队列上限。

WebSocket 断线重连和离线消息队列不是靠单个 API 实现的,而是需要手动设计状态管理、重连策略和本地缓存机制。核心在于:连接断开时暂存待发消息,恢复连接后按序重发,并避免重复发送或丢失。
监听连接状态并实现自动重连
WebSocket 本身不提供重连能力,需监听 onclose 和 onerror 事件,配合指数退避策略发起重试。
- 用布尔标志(如
isConnecting)防止重复调用new WebSocket() - 首次失败后延迟 100ms 重连,每次失败后延迟翻倍(如 100 → 200 → 400ms),上限建议 5–10 秒
- 设置最大重试次数(如 10 次),超限后触发业务层告警或降级提示
- 连接成功后重置重试计数器,并调用
replayQueue()尝试发送积压消息
维护内存中的离线消息队列
所有调用 ws.send() 的消息,在确认送达前都应进入队列;仅当收到服务端 ACK 或超时后才移出。
- 队列用数组或 Map 存储,每条消息建议带唯一 ID、时间戳、原始数据、重试次数
- 发送前检查
ws.readyState === WebSocket.OPEN,否则直接入队不报错 - 发送成功后,服务端应返回对应 ID 的确认响应;前端监听消息,匹配 ID 并从队列中删除
- 对未确认消息设置超时(如 15 秒),超时后自动重发(最多 3 次),再失败可标记为“投递失败”供上层处理
避免重复与乱序的关键细节
重连后若服务端未做会话续传,直接重发可能造成重复;若无序发送又可能打乱业务逻辑。
立即学习“Java免费学习笔记(深入)”;
- 服务端需支持“消息幂等性”——根据客户端消息 ID 去重,而非依赖顺序
- 客户端队列严格 FIFO,重连成功后按入队顺序逐条重发,不并发发送
- 连接重建后,先发一个“会话恢复请求”,服务端返回已接收的最新消息 ID,客户端据此截断或跳过已确认消息
- 对实时性要求高的消息(如心跳、指令),可设为“不入队”,失败即丢弃并通知上层
补充:持久化与内存限制
纯内存队列在页面刷新后清空,如需更强可靠性,可结合 IndexedDB 或 localStorage 缓存待发消息。
- 只对关键业务消息(如订单提交、聊天文本)做持久化,避免写入频繁拖慢性能
- 设置队列长度上限(如 100 条),超出时按时间或优先级丢弃旧消息,并通知用户“部分操作可能未同步”
- 页面卸载前(
beforeunload)尝试 flush 队列,但不阻塞,因浏览器可能强制终止


















