新手用workerman主动推送信息,必须先让服务端具备接收外部指令并转发给指定客户端的能力;需确认php≥7.4、安装think-worker、正确配置websocket协议、启动text worker监听端口用于接收推送指令、通过curl或gateway::sendtouid触发推送,并确保前端正确连接与绑定uid。

新手用Workerman主动推送信息,必须先让服务端具备接收外部指令并转发给指定客户端的能力,而不是直接在业务逻辑里调用send方法——因为WebSocket连接是长生命周期的,业务代码通常运行在HTTP请求上下文中,无法直接访问在线connection对象。
第一步:确认基础环境与安装方式
检查PHP版本是否≥7.4(Workerman 4.x要求),执行php -v验证;确认已安装Composer且可全局调用。
进入你的ThinkPHP项目根目录,执行:composer require topthink/think-worker。若使用TP6且PHP≥8.0,建议加@dev后缀避免依赖冲突:composer require topthink/think-worker:@dev。
安装完成后,config目录下会自动生成worker_server.php和worker.php两个配置文件——【不要手动修改worker.php里的socket地址为http://】,WebSocket服务必须用websocket://协议,写成http://会导致前端连接失败且无报错提示。
第二步:启动一个可监听内部推送的Worker服务
在app/command目录下创建PushServer.php命令类(非必须,但比改默认Worker更可控):
运行php think make:command PushServer生成骨架文件,然后编辑该文件,在execute方法中写入:
实例化WebSocket Worker监听2346端口 → 实例化Text协议Worker监听5678端口 → 给Text Worker绑定onMessage回调,解析JSON格式的推送指令 → 用Gateway::sendToUid()或Gateway::sendToAll()完成真实推送。
关键点:Text Worker端口(如5678)必须在服务器安全组中放行入方向,否则其它PHP脚本curl请求会被拒绝连接。
第三步:从任意业务位置触发推送
方法一:用cURL向Text Worker发起POST请求
构造请求URL为http://127.0.0.1:5678,body传原始JSON字符串:{"uid":"1001","content":"订单已支付"},注意结尾必须带换行符\n——【缺少\n会导致Workerman内部协议解析失败,消息静默丢弃】。
方法二:在TP控制器中封装推送函数
引入use GatewayWorker\Lib\Gateway;,直接调用Gateway::sendToUid('1001', '订单已支付');。此方式仅在GatewayWorker模式下有效,且要求businessWorker与gateway在同一进程组或启用Redis分布式支持。
方法三:用定时器轮询推送(仅测试用)
在Worker的onWorkerStart中添加Timer::add(5, function(){ Gateway::sendToAll('当前时间:'.date('H:i:s')); }); ——这步操作起来很简单,但生产环境严禁使用,会造成连接池阻塞。
第四步:前端建立连接并监听消息
确保Nginx已配置WebSocket代理(若部署在LNMP环境),location块中必须包含proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "Upgrade";两行,缺一则连接降级为HTTP短轮询。
前端JavaScript使用原生WebSocket连接ws://your-domain.com:2346,连接成功后发送初始化包{type:"init",uid:"1001"},服务端收到后将该连接绑定到uid标识下,后续所有sendToUid("1001",...)才会命中。
监听ws.onmessage事件,对返回内容做JSON.parse处理——如果后端推送的是纯字符串而非JSON对象,前端无需解析,直接event.data即可使用。











