Workerman 不直接支持 Sec-WebSocket-Protocol 透传,需在 onWebSocketConnect 中解析 $connection->httpHeader['sec-websocket-protocol'] 并手动构造 101 响应,或改用应用层协议协商提升兼容性。

Workerman 本身不直接解析或透传 Sec-WebSocket-Protocol 请求头,但你可以通过手动读取握手请求、校验并响应子协议来实现兼容。关键在于:在 WebSocket 握手阶段介入,控制响应头。
如何在 onConnect 中获取并校验 Sec-WebSocket-Protocol
Workerman 的 onConnect 回调中,$connection 对象尚未完成 WebSocket 升级,此时原始 HTTP 请求头仍可访问。你需要从 $connection->getRemoteIp() 之后立即检查 $connection->context->http_request_header(需确保使用 WebServer 或启用 HTTP 解析);更可靠的方式是改用 Worker + 手动解析握手数据流——即监听原始 TCP 连接,在 onMessage 的首次数据中解析 HTTP GET 请求行和头。
- 实际可用路径:继承
WebSocketConnection并重写onWebSocketConnect(仅限 Workerman 4.1+),该回调会在握手完成前触发,且$connection->httpHeader已解析好 -
Sec-WebSocket-Protocol值位于$connection->httpHeader['sec-websocket-protocol'],注意它是字符串(逗号分隔)而非数组,需array_map('trim', explode(',', ...))拆解 - 若使用
WebServer,必须设置$webserver->reusePort = true并确认未被 Nginx/Apache 提前终止 WebSocket 升级(它们可能过滤掉自定义协议头)
如何让 Workerman 在握手响应中返回选定的子协议
Workerman 默认响应头固定,不支持动态写入 Sec-WebSocket-Protocol。你必须在握手完成前拦截默认响应,并手动发送带协议头的 101 切换协议响应。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 在
onWebSocketConnect中调用$connection->destroy()阻止默认升级流程 - 用
$connection->send()手动构造响应,例如:HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: xxxxx Sec-WebSocket-Protocol: chat
-
Sec-WebSocket-Accept必须按 RFC6455 计算:对Sec-WebSocket-Key拼接"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"后做 SHA1 base64 —— Workerman 内置了Worker::generateWebsocketAccept($key)可直接复用 - 注意:手动响应后,连接状态不会自动变为 WebSocket 模式,后续收发二进制帧需自行处理掩码、分片等逻辑,不推荐全手动实现
更稳妥的替代方案:用 Workerman 的 WebSocketWorker + 中间层适配
放弃在底层硬改握手,转而把子协议语义移到应用层处理——这是多数生产项目的实际做法。
- 客户端仍发送
Sec-WebSocket-Protocol: v1.chat, v2.notify,服务端忽略该头,照常升级 - 连接建立后,客户端立刻发一条文本帧如
{"type":"handshake","protocol":"v1.chat"},服务端在onMessage中解析并绑定该连接的协议上下文到$connection->protocol - 后续所有消息根据
$connection->protocol做路由、序列化或权限校验,例如v1.chat用 JSON,v2.notify用 MsgPack - 优势:不依赖底层 HTTP 头解析稳定性,兼容 Nginx 反向代理(它通常会剥离
Sec-WebSocket-Protocol),也避免手动管理 WebSocket 帧格式
真正棘手的不是“怎么写”,而是当你的服务部署在多层代理后,Sec-WebSocket-Protocol 很可能在到达 Workerman 前就被静默丢弃——这时硬要透传反而导致不可靠。应用层协商虽然多一次往返,但可控性高得多。

















