GatewayWorker 与 ThinkPHP 是并行运行、职责分离、网络通信协作的关系,不可嵌入其生命周期;须独立部署、解耦隔离,通过 GatewayClient 单向推送,配置地址严格一致,并用队列异步处理推送任务。

GatewayWorker 是基于 Workerman 的长连接应用框架,它和 ThinkPHP 不是“嵌入关系”,而是并行运行、职责分离、通过网络通信协作的关系。强行把 GatewayWorker 塞进 ThinkPHP 生命周期(比如在控制器里 require 启动脚本或调用 Worker::runAll())会导致自动加载失效、进程卡死、Class not found 等问题。
核心原则:解耦部署,单向推送
GatewayWorker 必须作为独立服务启动,与 ThinkPHP 项目物理隔离、进程隔离、加载器隔离:
- ThinkPHP 负责业务逻辑(登录、发消息、查状态等 HTTP 请求处理)
- GatewayWorker 只负责维持 TCP/WebSocket 连接、转发数据、执行广播/单推等网络操作
- ThinkPHP 需要向客户端推送时,通过
GatewayClient发起一次轻量级 TCP 请求,不阻塞 Web 接口 - 客户端连接的是 GatewayWorker(如
ws://127.0.0.1:8282),不是 ThinkPHP 的 Web 服务器
目录结构建议:同级隔离,避免混杂
不要把 GatewayWorker 放进 app/、public/ 或 extend/ 目录。推荐结构如下:
./my_project/ ← ThinkPHP 项目根目录 ├── app/ ├── public/ ├── vendor/ └── ... ./gateway/ ← GatewayWorker 独立根目录(与 my_project 同级) ├── Applications/ ├── start.php ├── start_gateway.php ├── start_businessworker.php ├── start_register.php └── vendor/ ← 自带的 workerman/gateway-worker 依赖
这样可彻底规避 ThinkPHP 自动加载对 GatewayWorker 启动流程的干扰。
立即学习“PHP免费学习笔记(深入)”;
关键配置必须严格一致
GatewayClient 能否连通,取决于三个地址完全匹配:
-
start_gateway.php中设置的$gateway->lanIp和$gateway->startPort(例如'127.0.0.1'和9502) -
start_register.php中注册地址(如'127.0.0.1:1236')需被所有进程共用 - GatewayClient 初始化时传入的地址:
new GatewayClient('text://127.0.0.1:9502')
运行 netstat -tuln | grep 9502 确认监听地址是 127.0.0.1:9502 还是 0.0.0.0:9502;若需外网访问,必须设为 0.0.0.0 并开放对应端口。
安全推送:用队列+异步,别在控制器里硬推
直接在控制器中同步调用 Gateway::sendToUid() 推送大量用户,会导致接口响应变慢甚至超时。正确做法:
- 将推送任务写入消息队列(如 Redis List、TP 的 think-queue)
- 由独立的命令行消费者(
php think queue:work)异步执行推送 - 或使用 GatewayWorker 内置的
onMessage+ 定时器 + 业务 Worker 协作完成复杂逻辑
GatewayClient 仅用于“触发”动作,不承载业务判断。



















