Workerman 默认不自动拒绝非法WebSocket握手,需在onConnect中手动校验Upgrade、Connection、Sec-WebSocket-Key、Origin、Host等头字段并主动close;禁用错误输出以防响应污染导致隐式失败。

Workerman 默认对 WebSocket 握手有基础协议校验,但不会自动拒绝所有非法握手——它依赖你显式配置和主动拦截。若想在握手阶段就拦截不合规请求(比如缺少 Upgrade 头、Sec-WebSocket-Key 格式错误、非 websocket 协议升级等),需手动介入 onConnect 回调或使用中间件逻辑,在 HTTP 请求解析完成但连接尚未升级前做判断。
关键校验点必须手动实现
Workerman 的 Worker 启动为 websocket:// 时,会自动处理 RFC 6455 握手流程,包括生成 Sec-WebSocket-Accept,但它不会主动拒绝以下常见非法情况:
- 请求头中
Upgrade值不是小写websocket(如WebSocket、WEBSOCKET或缺失) -
Connection头不含Upgrade(大小写敏感,不能是upgrade或keep-alive, upgrade以外的组合) -
Sec-WebSocket-Key为空、长度不对(必须是 24 字节 Base64 编码)、含非法字符 - 请求方法不是
GET,或 URI 不符合预期(如要求固定路径/ws,但客户端访问了/api)
如何在握手前拦截并拒绝
Workerman 并未暴露“握手前钩子”,但可通过以下方式在连接建立初期精准干预:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 在
onConnect回调中,用$connection->getRemoteIp()和$connection->context->request(需开启http解析)获取原始请求对象 - 若使用
WebServer+Worker混合模式,可在onMessage前检查$connection->isWebsocketConnection === false,说明握手未成功,此时可$connection->close() - 更可靠的做法:改用
HttpServer监听,自己解析请求头,对非法握手直接返回400 Bad Request并关闭连接,不交由 WebSocket 层处理 - 示例片段(在
onConnect中):
<?php
if (!$connection->isWebsocketConnection) {
$connection->close();
return;
}
// 继续校验 Sec-WebSocket-Key 等字段
$key = $connection->context->request->header['sec-websocket-key'] ?? '';
if (empty($key) || strlen(base64_decode($key, true)) !== 16) {
$connection->close();
return;
}Origin 和 Host 校验也得自己加
Workerman 不做跨域 Origin 校验,默认放行所有来源。若需拒绝非法来源的握手请求:
- 读取
$connection->context->request->header['origin'] - 比对白名单域名(注意:空 Origin 或
file://场景也要考虑) - 不匹配时调用
$connection->close(),不要等进入onMessage - Host 头校验同理,尤其在 Nginx 反代后,
$host可能被覆盖,需结合X-Forwarded-Host判断
避免响应体污染导致隐式失败
即使你写了
return或exit,只要在握手响应已发送后还输出任何内容(如 warning、BOM、echo),浏览器就会判定握手失败,且不报错。务必做到:- 所有校验逻辑放在
onConnect尽早位置 - 禁用 PHP 错误显示:
ini_set('display_errors', 'Off') - 确保没有意外的
var_dump、print_r或日志写入到标准输出 - 用抓包工具(如 Wireshark 或浏览器 Network 面板)确认是否真返回了
101 Switching Protocols
- 读取

















