hyperf 路由不支持 server 参数,因其路由系统(基于 fastroute)仅负责 uri 和方法匹配,不感知 server;实际由 server.php 中各 server 的 name 及其 callbacks[on_request] 所绑定的处理器(如 httpserver::onrequest)决定路由执行上下文。

Hyperf 路由本身不接受 server 参数,server 是路由生效的前提条件,不是路由定义的选项。 你不能在 Router::get() 或 addGroup() 里传 server 字段;真正控制“哪个 server 处理哪条路由”的,是 servers 配置里的 name 和路由注册时隐含的 server 绑定逻辑。
为什么 Router::get() 没有 server 参数?
Hyperf 的路由系统(基于 fast-route)本身不感知 server;它只负责匹配 URI 和方法。实际哪个 server 实例来执行路由分发,取决于:
-
config/autoload/server.php中servers数组里每个 server 的name(如'http'、'ws'、'jsonrpc-http') - 每个 server 的
callbacks[Event::ON_REQUEST]是否指向了对应的 Server 类(如Hyperf\HttpServer\Server::class) - 框架启动时,会为每个
SERVER_HTTP类型的 server 实例初始化一个独立的Dispatcher,并绑定到该 server 的 onRequest 回调中
换句话说:路由规则被加载进内存后,是由具体 server 实例的 onRequest 回调触发 dispatch 的——不是路由自己选 server,而是 server 主动去 dispatch 它自己的那套路由。
怎么让某条路由只在特定 server 上生效?
靠的是「server 启动时加载的路由文件」和「中间件/控制器的协议适配性」,而非路由函数参数。常见做法:
- HTTP 路由默认只对
name => 'http'的 server 生效,因为只有它绑定了Hyperf\HttpServer\Server::onRequest - WebSocket 路由必须用
@OnMessage等注解写在WebSocketController里,且只被SERVER_WEBSOCKET类型的 server(如name => 'ws')捕获 - JSON RPC HTTP 接口路由需配合
Hyperf\JsonRpc\HttpServer::onRequest,所以只在name => 'jsonrpc-http'的 server 上走通 - 若你启用了多个 HTTP 类型 server(比如
name => 'admin'和name => 'api'),它们共享同一份路由表,但可通过中间件判断$request->getUri()->getHost()或路径前缀分流
配置多 server 时路由的实际归属逻辑
看 config/autoload/server.php 的典型片段:
'servers' => [
[
'name' => 'http',
'type' => ServerInterface::SERVER_HTTP,
'port' => 9501,
'callbacks' => [Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest']],
],
[
'name' => 'admin',
'type' => ServerInterface::SERVER_HTTP,
'port' => 9503,
'callbacks' => [Event::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest']],
],
],
这两个 server 都是 SERVER_HTTP 类型,都用了同一个 onRequest 处理器,因此都会加载并执行 config/routes.php 里全部路由。但你可以:
- 在中间件中用
$server = $request->getAttribute('server');获取当前 server 实例,再读取其name属性做分支 - 用
Router::addGroup('/api', ...)和Router::addGroup('/admin', ...)显式分离路径空间 - 不共用路由文件:改用
Hyperf\HttpServer\Router\Router的静态方法在不同 server 启动阶段分别注册(需自定义Process或Callback)
容易被忽略的关键点
很多人试图在 Router::get() 第三个参数里加 'server' => 'admin',这不会生效——该参数只认 middleware、name、group 等键。真正决定路由“在哪跑”的,是 server 配置的 name 和它的 callbacks 指向的处理器类。如果你看到某条路由没响应,先确认对应 server 是否已启动、端口是否监听、onRequest 回调是否正确绑定,而不是检查路由语句有没有写错 server 参数。











