WebSocket关闭码需严格遵循协议语义:标准码1000–1015用于通用场景(如1000表正常关闭,1001表即将离开),自定义码4000–4999须双方约定且具唯一业务动因,禁用1006等危险码及非法值,reason字符串限123字节、不得含敏感信息。

WebSocket 关闭代码不是随意填的数字,而是协议定义的语义化标识符,直接影响故障定位、重连策略和日志归因。用错码不仅掩盖真实问题,还可能让服务端无法区分业务退出和系统崩溃。
标准关闭码(1000–1015)的核心业务含义
这些由 IANA 官方注册的码,含义明确、跨平台一致,应优先用于主动关闭场景:
- 1000(NORMAL_CLOSURE):用户主动退出、功能完成、页面正常跳转——代表“我完成了,可以干净收尾”
- 1001(GOING_AWAY):客户端即将离开(如关闭标签页、小程序退后台)、服务端主动下线——强调“非错误,但不可恢复”
- 1002(PROTOCOL_ERROR):收到非法帧、序列错乱、opcode 不支持——说明通信层已失序,需检查 SDK 或中间件兼容性
- 1003(UNSUPPORTED_DATA):对方发来无法解析的数据类型(如二进制但本端只接受文本)——常出现在版本不匹配或配置错误时
- 1009(MESSAGE_TOO_BIG):单条消息超长被拒绝——对应服务端 maxPayload 设置或客户端分片逻辑缺陷
- 1011(SERVER_ERROR):服务端发生未捕获异常(OOM、空指针、DB 连接池耗尽等)——这是你该立刻查服务日志的信号
应用自定义码(4000–4999)的设计原则
这个区间专为业务逻辑保留,但必须双方约定,不能仅靠客户端单方面定义:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 4001:登录态失效(token 过期,需跳登录页)
- 4002:权限变更(用户被踢出多端登录)
- 4003:业务限流(当前连接数超配额)
- 4004:设备离线通知(IoT 场景中终端主动上报断连)
- 避免使用 4999 等“兜底码”,每个码应有唯一、可追溯的业务动因
必须避开的“危险码”及后果
以下状态码要么协议禁止、要么语义冲突,误用会直接触发异常:
- 1006(ABNORMAL_CLOSURE):它不是你调 close() 时传的,而是客户端在 TCP 断开且没收到任何关闭帧时自动生成的占位码——日志里查不到来源,也无法携带 reason,纯属排障黑洞
-
0、999、5000+、负数、字符串:调用
ws.close()时传入会立即报错 "the code must be...",连接卡在 CLOSING 状态,后续 send() 失败,甚至间接导致 1006 - 1004、1005、1007–1010、1012–1014:RFC 明确保留未定义,部分浏览器/库会拒绝识别或静默转为 1006
reason 字符串的实用边界
它不是日志字段,而是随关闭帧传输的轻量说明,需严格约束:
- 长度 ≤ 123 字节(不是字符数),中文字符按 UTF-8 占 3 字节计算,10 个汉字就接近上限
- 禁止含敏感信息(token、手机号、内部错误堆栈)——它可能被中间代理记录或前端控制台明文打印
- 推荐格式:
"user_logout_v2"、"quota_exceeded_202606",用下划线分隔、带时间戳或版本号便于追踪 - 服务端可通过
event.reason读取,但不保证送达(网络丢包、代理截断),关键状态必须走 HTTP 接口同步

















