监听 WebSocket 的 close 事件需立即绑定 ws.onclose 回调,通过 event.code、event.reason 和 event.wasClean 判断断开性质并决策重连或清理;它是最可靠的连接终结标志,比 onerror 更稳定,须配合防重入、资源清理、指数退避重连及应用层心跳机制保障连接健壮性。

监听 WebSocket 的 close 事件,核心是绑定 ws.onclose 回调函数,并在其中通过 event.code、event.reason 和 event.wasClean 判断断开性质,再决定是否重连或清理资源。它不是“连接失败”的唯一信号,但却是连接终结的确定性标志。
onclose 是连接终止的可靠入口
只要连接真正结束(无论服务端关闭、网络中断、主动调用 close()),onclose 都会触发。它比 onerror 更稳定——例如错误码 1006(异常中断)只走 onclose,完全不触发 onerror。
- 务必在
new WebSocket(url)后立即绑定,避免错过事件 - 不要在
onclose中再次调用ws.close(),此时连接已不可用 - 可结合
ws.readyState辅助判断:触发时通常为CLOSED (3)或已变为CLOSING (2)
通过 event 属性区分断开类型
onclose 回调接收一个 CloseEvent 对象,三个关键属性能帮你做决策:
-
event.code:标准关闭码。常见值有
1000(正常关闭)、1006(异常中断,如 TCP RST)、1011(服务端内部错误) -
event.reason:服务端传来的可选字符串说明,如
"user logout"或空字符串 -
event.wasClean:布尔值。
true表示协议级干净关闭(发了 close frame);false多数对应 1006 类型,意味着连接被强制切断
示例中可跳过 code === 1000 的重连,但对 wasClean === false 或 code === 1006 应立即启动恢复逻辑。
配合重连机制防止状态混乱
仅监听不够,需闭环处理:断开后重建连接,同时避免重复创建、残留监听或消息错乱。
- 设置防重入标志(如
isReconnecting = true),重连成功后再置为false - 每次新建前,先清理旧实例:
oldWs?.onmessage = null; oldWs?.onerror = null;,并尝试oldWs?.close(1000, 'reconnecting') - 使用指数退避延迟重试:首次 500ms,之后每次翻倍,上限建议 30s,总次数不超过 10 次
- 维护全局
currentWs引用,所有send()前校验currentWs.readyState === WebSocket.OPEN
别忽略心跳与假在线检测
单纯依赖 onclose 会漏掉“连接未断但已失效”的情况(比如 NAT 超时、服务端卡死)。必须叠加应用层心跳:
- 客户端每 15–30 秒发送自定义
{"type":"ping"}消息 - 等待服务端响应
{"type":"pong"},超时(如连续 2 次无响应)即主动close()并触发重连 - 心跳超时逻辑独立于
onclose,避免被网络抖动干扰判断


















