WebSocket close() 必须传合法 code(1000–4999)和 reason 才能准确表达意图;禁用 1004/1005/1006;reason 长度限 123 字节且不加密;关闭是双向握手,服务端未响应则连接卡在 CLOSING。

WebSocket 的 close() 方法必须传参数才能表达真实意图,不传参虽能断连,但服务端无法区分是“正常退出”还是“意外掉线”——这直接影响重连逻辑和日志归因。
哪些 code 值合法?别踩 1004/1005/1006 这几个坑
code 是 16 位无符号整数,只接受 1000–4999 范围内的值。超出会抛 InvalidAccessError;低于 1000 或高于 4999 都算非法。
-
1000:标准正常关闭,适合用户主动登出、页面卸载前清理 -
1001:明确表示“端点离开”,比如beforeunload中调用,浏览器和服务端都认这个语义 -
1002/1003:协议错误或数据类型不支持,一般由底层自动触发,手动少用 -
1004、1005、1006:RFC 已废弃,1006实际上是异常关闭的兜底码(网络中断等),**绝不能主动传** -
4000–4999:留给业务自定义,比如4001表示“token 过期”,但需客户端和服务端提前约定
reason 字符串不是可有可无的调试字段
它会被 UTF-8 编码后塞进关闭帧,长度上限是 123 字节 —— 不是字符数,中文字符占 3 字节,123 字节 ≈ 41 个汉字。超长会静默截断或报错。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 服务端可通过
event.reason(Node.jsws库)或CloseReason.getReasonPhrase()(Java)读取 - 前端在
onclose回调里也能拿到:event.reason,可用于前端埋点或提示用户 - 别传敏感信息(如 token、用户 ID),关闭帧不加密,中间设备可能窥探
- 空字符串或
undefined都会被当成空 reason,不影响流程,但失去上下文
调用后状态立即变 CLOSING,但发送已禁用
执行 ws.close(1001, "Page is navigating away") 后,ws.readyState 立即从 OPEN (1) 变成 CLOSING (2),此时:
-
ws.send()会直接抛InvalidStateError,不能再发任何消息 -
onmessage仍可能收到最后几条服务端推送,要小心处理(比如忽略或快速丢弃) - 不要在
CLOSING状态下设新监听器或启动定时器,资源清理应放在onclose里 - 如果服务端迟迟不回关闭帧,浏览器通常在几秒后强制转为
CLOSED (3),event.code可能变成1006
真正容易被忽略的是:关闭帧的双向确认不是“发完就完”,而是协议级握手。哪怕你传了 1000,如果服务端没按 RFC 返回相同 code 的响应帧,连接就卡在 CLOSING,前端也收不到 onclose,资源实际没释放。

















