只有 ws.readyState === WebSocket.OPEN(1)才可安全收发数据;0为CONNECTING(连接中)、1为OPEN(就绪)、2为CLOSING(关闭中)、3为CLOSED(已关闭),构造后立即检查无效,须在onopen中确认。

只有 ws.readyState === WebSocket.OPEN 才代表连接真正就绪,可安全收发数据;其他值都不行,直接 send() 会抛 InvalidStateError。
WebSocket readyState 的四个合法值分别代表什么
它不是布尔值,也不是“在线/离线”开关,而是连接生命周期的精确快照:
-
WebSocket.CONNECTING(0):实例已创建,但 DNS、TCP 握手、HTTP Upgrade 等步骤尚未完成;此时调用send()必报错 -
WebSocket.OPEN(1):握手成功,通道打通,send()和onmessage都可正常工作 -
WebSocket.CLOSING(2):close()已被调用(本地或服务端),但关闭帧可能未收完,仍可能收到最后几条消息 -
WebSocket.CLOSED(3):连接彻底终结,不可复用;若要重连,必须new WebSocket(...)新建实例
为什么不能 new WebSocket() 后立刻检查 readyState
构造函数是异步发起连接的,new WebSocket(url) 返回瞬间,readyState 几乎总是 0,但连接远未建立——这不是延迟问题,而是设计如此。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 轮询
readyState或用setTimeout等固定时间点判断,既不可靠(弱网下超时难定),也浪费资源 - 正确时机在
onopen回调内:触发即表示状态已稳定为1,且网络层确认可达 - 错误处理应依赖
onerror:它可能在CONNECTING阶段就触发,此时readyState通常仍是0或已退为0
send() / close() 前必须做的状态校验
不校验就调用是生产环境 InvalidStateError 的头号来源。
- 发消息前只认
WebSocket.OPEN:if (ws.readyState === WebSocket.OPEN) ws.send(data) - 允许对
OPEN或CLOSING调用close()(重复调用无副作用);但绝不要对CONNECTING或CLOSED调用 - 老环境(如 Android 4.4 WebView)可能不支持
WebSocket.CONNECTING等常量,可回退用数字,但务必加注释说明含义
重连逻辑里 readyState 最容易踩的坑
重连不是“看到不是 1 就新建”,而要结合事件和终态判断:
- 仅在
onclose或onerror触发后才启动重连流程 - 重连前先确认
ws.readyState === WebSocket.CLOSED(即3),避免对仍在CLOSING(2)的实例重复操作 - 新建实例前,显式设
ws = null,否则旧实例监听器可能残留,导致多次触发onopen或内存泄漏 -
readyState === 1不等于“网络通畅”——断网后它可能维持数秒不变,需配合心跳 +onerror+ 超时检测综合判断










