只有 ws.readyState === WebSocket.OPEN 才表示连接真正就绪,可安全收发消息;其值0/1/2/3分别对应CONNECTING/OPEN/CLOSING/CLOSED四种精确状态,new后立即检查无效,须在onopen中确认,send/close前必须校验状态,重连需避免状态误判。

只有 ws.readyState === WebSocket.OPEN 才表示连接真正就绪,可安全收发消息;其他值都不行,硬写 === 1 或 if (ws.readyState) 都会出问题。
readyState 的四个值到底对应什么状态
它不是布尔开关,而是精确的生命周期快照,每个数字有唯一含义:
-
0(WebSocket.CONNECTING):实例已创建,但 DNS、TCP 握手、HTTP Upgrade 全都没完成;此时调用send()必抛InvalidStateError: Still in CONNECTING state -
1(WebSocket.OPEN):握手成功,通道打通,send()和onmessage可用 -
2(WebSocket.CLOSING):close()已被调用,关闭帧可能还没收完;还能收到残留消息,但不能再发新数据 -
3(WebSocket.CLOSED):连接彻底终结,不可复用;重连必须new WebSocket()新建实例
注意:WebSocket.CONNECTING 等常量在 Android 4.4 WebView 或旧版 Safari 中可能未定义,建议 fallback 到数字比较,但务必加注释说明含义。
为什么不能 new WebSocket() 后立刻检查 readyState
构造函数是异步发起连接的,new WebSocket(url) 返回瞬间,readyState 几乎总是 0,但连接远未建立——这不是延迟问题,而是设计如此。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 轮询
readyState或用setTimeout等固定时间点检查,既不可靠(弱网下超时难定),也浪费资源 - 正确时机在
onopen回调内:触发即表示状态已稳定为1,且网络层确认可达 - 错误处理应依赖
onerror:它可能在CONNECTING阶段就触发,此时readyState通常仍是0
send() 和 close() 前必须做的状态校验
不校验就调用是生产环境 InvalidStateError 的头号来源:
- 发消息前只认
WebSocket.OPEN:if (ws.readyState === WebSocket.OPEN) ws.send(data) - 允许对
OPEN或CLOSING调用close()(重复调用无副作用);但绝不要对CONNECTING或CLOSED调用 - 重连逻辑里常见错误:仅凭
ws.readyState !== 1就新建连接,结果在CLOSING(2)时并发多个实例,或CLOSED(3)后未清理定时器导致内存泄漏
重连和调试中最容易忽略的细节
这些点不写进日志、不加断点就很难发现:
-
onopen触发时readyState一定是1,但这只是“通道就绪”,不是“业务就绪”——服务端可能还在鉴权,此时发业务消息会被静默丢弃 -
readyState === 1不等于“网络通畅”:断网后它可能维持数秒不变,需配合心跳 +onerror+ 超时检测综合判断 - 你在 DevTools 里敲
console.log(ws.readyState)看到1,只代表那一毫秒的状态快照;它无法反映是否刚收到onclose但事件循环还没执行回调,或正处在CLOSING → CLOSED的不可预测过渡期
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










