WebSocket连接状态需精准识别并响应:CONNECTING时禁用发送,OPEN时启动心跳,CLOSING时停止发消息,CLOSED时清理资源并按close事件中的wasClean、code、reason决定是否重连;每次send前须校验readyState为OPEN,避免误操作引发错误。

WebSocket 连接状态变化直接影响前端通信的可靠性与用户体验。状态切换本身不可怕,真正的问题在于:状态变更未被及时感知、未做相应处理,或在错误状态下执行了非法操作(比如向 CLOSING 或 CLOSED 的 socket 发送消息),从而引发静默失败、重复重连、内存泄漏甚至界面卡顿。
准确识别并响应关键状态变化
WebSocket 的 readyState 是判断连接可用性的唯一权威依据,不能依赖“有没有收到消息”来推断是否在线。四个状态需区别对待:
-
CONNECTING(0):仅表示正在握手,此时调用
send()会抛错;应禁用发送按钮、显示“连接中”提示 - OPEN(1):唯一可安全收发消息的状态;建立后立即启动心跳定时器,避免被中间件(如 Nginx、负载均衡)静默断开
- CLOSING(2):说明关闭流程已启动,但尚未完成;不应再发送业务消息,可清理临时监听器,但不要立即新建连接
- CLOSED(3):连接彻底失效;需清除所有定时器、释放引用,并根据关闭原因决定是否重连
从 close 事件中提取真实断连原因
onclose 事件携带的 CloseEvent 对象比 onerror 更具诊断价值,重点看三个字段:
-
wasClean === false:几乎可判定为非正常中断(网络抖动、服务崩溃、代理切断),必须触发重连逻辑 -
code:1000 表示双方协商关闭,无需重连;1006 表示底层连接丢失,需指数退避重试;4000+ 通常是业务自定义码(如 token 过期),应跳转登录页而非重连 -
reason:服务端返回的字符串,可能包含调试线索(如"token expired"或"max connections reached"),可直接用于用户提示
防止状态误用导致的运行时错误
“WebSocket is already CLOSING” 类报错,本质是代码在连接进入不可用状态后仍试图操作 socket。规避方式很直接:
立即学习“前端免费学习笔记(深入)”;
- 每次调用
send()前,加一层if (socket.readyState === WebSocket.OPEN)判断 - 在
onclose和onerror回调里,显式将 socket 实例置为null,并清空所有相关定时器(如心跳、重连计时器) - 避免全局单例 socket 被多处无意复用;推荐封装成带状态管理的服务类,对外只暴露
send()、close()等受控方法
结合场景设计差异化恢复策略
不是所有断连都该无脑重连。需按业务语义区分处理:
- 聊天类应用:允许短暂离线,重连后需同步未读消息;若连续失败 3 次,降级为 HTTP 轮询并提示“网络不稳定”
- 行情/交易类应用:对数据连续性极度敏感;连接中断必须立即通知用户,且重连期间禁止下单操作,避免状态不一致
- 后台任务推送:可容忍延迟;断连后暂停接收,待重连成功再拉取最新任务快照,不追求消息零丢失


















