GatewayWorker 必须作为独立服务与ThinkPHP解耦运行,不可嵌入TP生命周期;启动脚本需用绝对路径加载Workerman自动加载器,GatewayClient连接地址须与start_gateway监听地址严格一致,并通过事件+队列实现安全推送。

GatewayWorker 启动失败:找不到 start_register 或 start_gateway
根本原因是 ThinkPHP 的自动加载机制和 GatewayWorker 的进程启动方式冲突——它不走 index.php 入口,而是直接 require 自己的启动脚本,导致 TP 的容器、配置、自动加载全失效。
正确做法是把 GatewayWorker 当作独立服务运行,和 ThinkPHP 项目共存但解耦。不要试图在 TP 控制器里 require Workerman/Autoloader.php 然后调 Worker::runAll(),这会卡死或报 Class not found。
- 将
GatewayWorker放在 ThinkPHP 项目根目录同级(如./gateway/),避免混入app/或public/ -
start_register和start_gateway必须用绝对路径加载Workerman/Autoloader.php,不能依赖 TP 的vendor/autoload.php - 所有业务逻辑(比如用户登录后推送)通过
GatewayClient发送,而不是在 Gateway 进程里调用 TP 模型
GatewayClient 调用报错:Connection refused 或 Invalid gateway address
这是最常卡住人的点:GatewayClient 默认连的是 127.0.0.1:9502,但你的 start_gateway 可能监听在 0.0.0.0:9502,也可能被防火墙/SELinux 拦了,甚至 PHP-FPM 用户没权限访问 socket 文件。
检查三件事:
- 确认
start_gateway中$gateway->lanIp和$gateway->startPort与GatewayClient初始化时传的地址一致,例如:new GatewayClient('text://127.0.0.1:9502') - 运行
netstat -tuln | grep 9502,看是否真有进程监听;如果只显示127.0.0.1:9502,外部请求进不来,得改成0.0.0.0:9502并确保安全组放行 -
GatewayClient必须在 PHP CLI 环境下测试(如php test_client.php),Web 请求中使用需注意超时和连接池问题,别在控制器里反复 new
ThinkPHP 中如何安全触发 Gateway 推送
不能在控制器里同步调用 GatewayClient 发送大量消息,否则接口会卡住;也不能把 GatewayWorker 进程塞进 TP 生命周期,否则 reload 后连接丢失。
推荐用「事件+队列」解耦:
- TP 中触发业务事件(如
UserLoginEvent),由监听器写入 Redis 或数据库标记待推送 - 单独起一个 Workerman 定时任务(非 Gateway 进程)轮询或订阅 Redis,再用
GatewayClient异步推,避免阻塞 Web 请求 - 若必须实时,用
Gateway::sendToUid()前先确保register进程正常,且客户端已通过GatewayClient::bindUid()绑定过 uid
示例关键片段:GatewayClient::sendToUid($uid, json_encode(['type'=>'msg', 'data'=>$content])),注意 $uid 是字符串,不是数字 ID。
部署后 Gateway 进程莫名退出或无法重连
Workerman 进程退出通常不会抛异常,而是静默消失,常见于内存溢出、未捕获异常、或系统 kill(OOM killer)。
上线前必做几件事:
- 在
start_gateway开头加ini_set('memory_limit', '512M'),Workerman 默认继承 PHP 配置,CLI 下常为 128M,不够用 - 所有回调函数(如
onMessage)必须 try-catch,否则一次未捕获异常会让整个 worker 进程退出 - 用
php start_gateway.php status查状态,别只看ps aux | grep gateway;用tail -f storage/logs/gateway.log(需提前配置Worker::$logFile)盯错误 - Linux 上用
systemd管理进程比nohup更稳,记得设置Restart=always和LimitNOFILE=65535
GatewayWorker 不是 ThinkPHP 插件,它是一套独立的长连接基础设施,越早接受这个事实,越少掉坑里。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










