WebSocket子协议是连接前的语义协商机制,通过Sec-WebSocket-Protocol头匹配字符串,要求客户端与服务端协议名完全一致(区分大小写及符号),不传或非法字符将导致握手失败。

WebSocket 子协议(Subprotocol)不是功能扩展,而是语义协商机制——它不改变传输方式,只让客户端和服务端在连接建立前就约定好“用哪套规则说话”。握手阶段通过 Sec-WebSocket-Protocol HTTP 头完成匹配,一旦选定,后续所有消息都必须严格遵循该协议定义的格式与交互逻辑。
子协议本质是字符串匹配
子协议名只是一个区分用途的字符串,比如 json-rpc、graphql-ws 或 chat.v1。服务端不做解析、不校验版本、不自动降级,只做三件事:
- 检查客户端传来的协议列表是否包含自己支持的项
- 从中选出一个(通常取第一个匹配项)
- 在响应头中原样回写
Sec-WebSocket-Protocol: xxx
客户端和服务端必须双向对齐
浏览器端调用 new WebSocket(url, ["json-rpc", "fallback.json"]),表示按顺序偏好;服务端如用 FastAPI,需明确写 await websocket.accept(subprotocol="json-rpc")。二者必须存在完全一致的字符串匹配,否则握手失败,报错提示“no response was received”。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 大小写、连字符、点号、版本号均视为不同协议(
json-rpc≠JSON-RPC≠json-rpc-v2) - 不传
subprotocol参数 → 服务端拒绝任何Sec-WebSocket-Protocol头 - 传空数组
[]或不传第二个参数 → 不发送该头部,等价于无子协议协商
协议名有严格字符限制
浏览器会拦截含非法字符的子协议名,例如空格、斜杠、控制符或不可见字符。错误提示为:Failed to construct 'WebSocket': The subprotocol contains invalid characters。合法协议名建议仅使用 ASCII 字母、数字、连字符和点号,长度适中,避免歧义。
子协议 ≠ 消息编码格式,但强烈建议保持一致
子协议本身不限制你用 JSON、Protobuf 还是二进制,但它定义了语义层规则:比如 graphql-ws 要求按特定结构发 connection_init、subscribe 等操作;json-rpc 要求带 id、method、params 字段。若协议名选了 json-rpc 却发纯二进制帧,服务端很可能以关闭码 1007(Invalid frame payload data)中断连接。

















