监听 WebSocket 状态应以 onopen/onclose/onerror 事件为主,readyState 仅为生命周期“上一帧”标记;send() 和 close() 前须校验 readyState,且需配合心跳与超时检测判断真实可用性。

监听 WebSocket 连接状态不能靠轮询 readyState,而应以事件驱动为主、状态校验为辅。它不是实时快照,而是生命周期的“上一帧”标记,直接读取容易误判。
用 onopen / onclose / onerror 响应真实状态变化
这些事件才是连接状态切换的可靠信号:
-
onopen:触发时
ws.readyState必为WebSocket.OPEN(即 1),表示握手完成、通道就绪;此时可安全调用send() -
onclose:触发时
ws.readyState已变为WebSocket.CLOSED(即 3),附带code和reason,说明关闭原因(如服务端主动断开、超时等) -
onerror:不等于断连,仅捕获协议层异常(如帧解析失败);它可能在
CONNECTING阶段就触发,此时readyState通常仍是 0
send() 和 close() 前必须校验 readyState
避免运行时错误的关键防护动作:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 发消息前只认
ws.readyState === WebSocket.OPEN;CLOSING状态下send()可能静默丢弃,CLOSED或CONNECTING下必抛InvalidStateError - 调用
close()时允许对OPEN或CLOSING状态执行(重复无副作用),但不要对CONNECTING或CLOSED调用 - 建议写成:
if (ws.readyState === WebSocket.OPEN) ws.send(data),而不是if (ws.readyState)或if (ws.readyState === 1)
别信 readyState === 1 就万事大吉
它只代表协议握手成功,不等于网络通畅或服务端已准备就绪:
- CDN(如 Cloudflare)可能在空闲 100 秒后单向关闭 TCP,此时
readyState仍显示 1,但下次send()会直接报错 - 服务端鉴权、会话初始化等异步操作未完成时,发业务消息可能被静默丢弃
- 需配合心跳机制(定时发 ping 消息 + 监听 pong 响应)和超时检测,才能真正判断“是否可用”
调试时正确查看 readyState 含义
开发阶段便于排查,可做语义映射:
- 定义常量:
const STATE = { CONNECTING: 0, OPEN: 1, CLOSING: 2, CLOSED: 3 } - 打印日志:
console.log('WS state:', ['CONNECTING','OPEN','CLOSING','CLOSED'][ws.readyState]) - 注意:在控制台手动敲
console.log(ws.readyState)看到 1,仅代表那一毫秒的状态,无法反映网络实际连通性或事件队列是否已处理

















