GatewayWorker 是基于 Workerman 构建的长连接通信框架,提供分组、广播、消息路由等 IM 能力,而 Workerman 仅负责底层网络 IO;三进程平级协作,消息下发必须经 Gateway 中转,不可直连客户端。

Workerman 是底层 socket 类库,GatewayWorker 是专为长连接通讯封装的框架
Workerman 本身不提供“用户分组”“广播”“客户端互发消息”这些 IM 场景高频能力,它只管网络层:收包、发包、多进程管理、协议解析(WebSocket/HTTP/TCP 自定义)。你得自己写逻辑把 onMessage 里的数据路由到对应 client_id 或 group,还得自己维护连接状态、心跳、断线重连通知——这些重复劳动 GatewayWorker 全帮你做了。
GatewayWorker 不是 Workerman 的“升级版”,而是基于它构建的上层框架。装 workerman/gateway-worker 会自动拉取 workerman/workerman,但反过来不行;卸载前者不会删后者,前提是 composer.json 里显式写了 workerman/workerman。
- 需要做聊天室、APP 推送、设备上下线通知?直接用 GatewayWorker,省掉 70% 连接管理胶水代码
- 只是写个内部 TCP 心跳探测服务,或短连接 HTTP API 网关?Workerman 更轻量,没冗余抽象
- 要用 UDP?GatewayWorker 不支持,必须退回 Workerman 原生写
UdpConnection
GatewayWorker 的三个核心进程不是父子关系,而是对等通信节点
很多人误以为 Register 是 master,Gateway 和 BusinessWorker 是 worker —— 实际上三者完全平级,靠长连接互相注册发现。这点直接影响部署方式和故障排查思路。
-
Register进程只干一件事:存所有 Gateway 的内部地址(127.0.0.1:9600这类),并广播给 BusinessWorker;它不处理任何业务,也不碰客户端连接 -
Gateway进程只做网络 IO:维持成千上万客户端连接、转发数据、发心跳、踢超时连接;它不执行 PHP 业务逻辑,所以崩溃也不会丢消息上下文 -
BusinessWorker才真正跑你的Events.php,调onMessage处理登录、发消息、加群等;但它压根不知道客户端长什么样,只认 Gateway 发来的$client_id和$gateway_client_id
这种分离意味着:你可以把 Gateway 部署在高带宽低 CPU 的机器上,BusinessWorker 部署在高 CPU 的机器上,两者通过内网通信 —— 但前提是它们都能连上同一个 Register 进程(或集群)。
“向用户推送消息”必须走 GatewayWorker 的 API,不能直接 echo 给 socket
新手常犯的错误:在 onMessage 里写 $connection->send(...),结果消息根本发不出去,或者只发给自己。因为 GatewayWorker 的设计里,BusinessWorker 和客户端之间**没有直连**,所有下发都必须经由 Gateway 进程中转。
- 发给单人:
GatewayClient::sendToClient($client_id, $data) - 发给某群:
GatewayClient::sendToGroup($group_id, $data) - 全局广播:
GatewayClient::broadcastMessage($data) - 注意:
$client_id是 Gateway 分配的唯一字符串(如"0000000000000001"),不是你业务系统的 uid;绑定 uid 到 client_id 要靠bindUid和unbindUid
如果漏掉 use GatewayClient; 或没在 start_business.php 中引入 GatewayClient 类,调用会静默失败,日志里也看不到报错 —— 这是最容易卡住的点。
Windows 开发 + Linux 部署时,路径和启动方式要手动对齐
官方 demo 在 Windows 下双击 bat 启动,Linux 下却要 php start.php start -d;而且 Applications/YourApp 目录结构必须严格匹配,否则 require_once 会找不到 Events.php。
- 别直接把 Windows 版 demo 整体扔进 ThinkPHP5 的
application/目录;建议新建独立目录如server/,再 symlink 或复制Applications/YourApp进去 - Linux 启动前务必检查:
start_gateway.php和start_business.php中的use路径、require_once的相对路径是否含 Windows 风格反斜杠\ - TP5 框架里想集成?不要改 TP 的入口文件去加载 GatewayWorker;正确做法是在 TP 根目录旁建
server/,用 supervisor 独立托管 GatewayWorker 进程,TP 只负责 HTTP 接口(如登录、获取 token)
跨平台最隐蔽的坑是文件权限和 SELinux:Linux 上 start.php 启动后没报错但进程立刻退出,大概率是 gateway 用户没权限读写 runtime/ 目录,或者 setuid 被禁用了 —— 这种问题不会抛 PHP 错误,得看 ps aux | grep gateway 和系统日志。









