Hyperf WebSocket 路由必须通过 Router::addServer('ws', ...) 绑定到 server.php 中定义的 'ws' 实例,仅支持 GET 方法,路径需与 onHandShake 中 request_uri 严格一致,控制器须实现 OnOpen/OnMessage/OnClose 接口,中间件需在 middlewares.php 中按 server name 配置。

路由必须绑定到 WebSocket Server 名称,不是 HTTP 那套
Hyperf 的 WebSocket 路由不走 Router::get() 或 Router::post(),它依赖 Router::addServer() 显式挂载到某个 WebSocket server 实例上。这个实例的 name 必须和 config/autoload/server.php 里定义的 WebSocket server 的 name 完全一致,否则请求根本进不到 WebSocket 生命周期里。
-
config/autoload/server.php中 WebSocket server 的name是'ws',那么路由就必须写Router::addServer('ws', ...) - 如果改成了
'websocket'或'mixed',路由块也得同步改,否则onHandShake回调压根不会触发 - 不能把 WebSocket 路由写在 HTTP 的
Router::get('/ws', ...)里——那只是个普通 HTTP 接口,和 WebSocket 握手无关
路由闭包里只能用 Router::get(),不支持 POST/PUT 等方法
WebSocket 连接建立是通过 HTTP GET 请求发起的(带 Upgrade: websocket 头),所以路由定义只认 GET。你在 addServer() 闭包里写 Router::post() 或 Router::any() 都无效,框架会忽略。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 正确写法:
Router::get('/', 'App\Controller\WebSocketController') - 路径支持变量,比如
/ws/{uid:\d+},但注意:这些参数只在onOpen()的$request对象里可用,onMessage()里拿不到 - 不要指望用路由参数做鉴权主逻辑——握手阶段还没走完中间件,建议在
onOpen()里手动校验或走 token 查询
控制器必须实现三个接口,且路径要匹配
路由指向的控制器类,必须同时实现 OnOpenInterface、OnMessageInterface 和 OnCloseInterface,缺一个,连接就会卡在握手后或断连异常。另外,onHandShake 回调默认只放行 / 或你显式配置的路径,如果路由是 /chat,但 onHandShake 里没判断 $request->server['request_uri'] === '/chat',Swoole 就会直接返回 400。
- 检查
onOpen()方法签名是否为public function onOpen($server, Request $request): void - 确保
$request->server['request_uri']和路由路径一致,不一致就手动 return false 或 throw 异常 - 若用注解方式(
@OnOpen),需确认类上有@WebSocketController,且该控制器被扫描到(检查scan配置)
别漏掉中间件注册点,middlewares.php 是独立入口
WebSocket 的中间件不走 HTTP 的全局中间件数组,它有自己的注册位置:config/autoload/middlewares.php,且必须以 server name 为键。如果你的 WebSocket server 名叫 'ws',中间件就得配成 'ws' => [AuthMiddleware::class],而不是塞进 'http' 或空数组里。
- 中间件执行时机在
onHandShake之后、onOpen之前,可用于鉴权或拒绝非法连接 - 中间件里不能调用
$response->withStatus()—— WebSocket 握手响应由 Swoole 底层控制,你只能return false终止握手 - 如果中间件抛异常,Hyperf 默认返回 500,但客户端看到的是连接被重置,建议 catch 后显式
return false
onHandShake 内部的 URI 判断必须严格一致,哪怕多一个斜杠或大小写不同,都会导致握手静默失败。Nginx 透传配置再完美,这一步错了一样连不上。


















