WebSocket连接的Header只能在onConnect回调中读取,因握手完成后即切换为帧通信、Header信息不再保留;需用$connection->getHeader('key')(key全小写)获取,如origin、sec-websocket-protocol等,并可存入$connection属性供后续使用。

WebSocket连接建立时的Header只能在onConnect里读
Workerman的WebSocket协议解析器在握手阶段(HTTP Upgrade)会把原始请求头完整保留,但只暴露给onConnect回调;一旦升级完成进入onMessage,就不再持有Header信息——因为WebSocket帧本身不带Header。
常见错误是试图在onMessage里调用$request->header()或$connection->getHeader(),这些方法根本不存在。WebSocket连接对象$connection没有Header访问接口,只有HTTP请求对象才有。
- 必须在
onConnect中处理Header,例如提取origin做来源校验、读取sec-websocket-protocol协商子协议 - Header key 全部转为小写,
$connection->getHeader('User-Agent')会失败,得写$connection->getHeader('user-agent') - 如果需要在后续
onMessage中使用Header数据,必须提前存到$connection属性上,比如$connection->origin = $connection->getHeader('origin');
怎么拿到Origin、Referer这些关键Header
浏览器发起WebSocket连接时,会带标准HTTP请求头,包括origin、referer、cookie等。Workerman在onConnect回调中通过$connection->getHeader()可直接读取。
注意:getHeader()返回的是字符串,不是数组;没有getHeaders()批量获取方法。想看全量,只能一个个试:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
-
$connection->getHeader('origin')→ 判断是否允许跨域连接 -
$connection->getHeader('cookie')→ 拿原始Cookie字符串,但不能直接解析,需手动parse_str()(不推荐,见下一条) -
$connection->getHeader('sec-websocket-key')→ 协议握手必需,框架内部已用,一般不用动 - 自定义Header如
X-Device-ID,写成$connection->getHeader('x-device-id')
为什么不能在onMessage里用Http::input()取Header
Http::input()是Workerman\Protocols\Http模块提供的统一输入入口,但它只对HTTP协议有效;WebSocket协议不走这个路径,Http::input('header.xxx')在WebSocket连接中始终返回null。
根本原因是:WebSocket握手完成后,连接已脱离HTTP语义,Workerman底层切换为WebSocket帧解析器,不再维护Http::input缓存。你看到的Http::input文档示例,全部基于http://协议启动的Worker。
- 别试图在
onMessage里requireWorkerman\Protocols\Http\Request再伪造请求对象——Header早已丢失,无法还原 - 如果业务强依赖Header(比如鉴权),必须在
onConnect里完成校验并决定是否$connection->close(),否则放行后就再无补救机会 - Cookie值若需复用,请在
onConnect中解析cookie头并存入$connection->cookie_data,避免每次消息都重复解析
nginx代理下如何拿到真实X-Forwarded-For和X-Real-IP
当WebSocket连接经过nginx反向代理时,原始客户端IP和部分Header会被覆盖。nginx需显式透传,且Workerman必须从onConnect的Header中读取,而不是靠$connection->getRemoteIp()(它返回的是nginx的IP)。
nginx配置关键项:
location /ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
- Workerman侧用
$connection->getHeader('x-real-ip')或$connection->getHeader('x-forwarded-for')获取 - 注意
X-Forwarded-For可能是逗号分隔的IP链,取第一个即可:explode(',', $connection->getHeader('x-forwarded-for'))[0] ?? '' - 如果nginx没配
proxy_set_header,这些Header在onConnect里就是null,没有fallback机制
onConnect,后面所有消息都无法追溯来源上下文——这是最容易被忽略的设计约束。

















