workerman实现php异步消息推送的核心是常驻内存、事件驱动与非阻塞i/o,通过websocket/tcp长连接实现服务端主动推送;推荐用gatewayworker支持分组/uid推送,结合内部通信或消息队列解耦业务与连接管理,并注重心跳保活、身份绑定及网络配置。

Workerman 做 PHP 异步消息推送,核心是利用其常驻内存、事件驱动、非阻塞 I/O 的特性,绕过传统 HTTP 请求-响应模型,建立长连接通道(如 WebSocket 或 TCP),让服务端能主动向客户端发消息。关键不在于“异步”本身有多神秘,而在于如何组织连接管理、消息分发和业务触发逻辑。
用 WebSocket 实现双向实时推送
这是最常用也最推荐的方式,尤其适合 Web 页面、小程序、App 等前端场景。
- 启动一个 WebSocket Worker,监听指定端口(如 2346),处理连接、心跳、断开等生命周期事件
- 客户端(HTML/JS)用
new WebSocket('ws://your-domain:2346')建立连接,服务端通过$connection->send($msg)单点推送,或遍历$worker->connections群发 - 为支持广播、分组、用户绑定等复杂场景,建议直接使用 GatewayWorker 组件——它把 Gateway(接入层)、BusinessWorker(业务逻辑层)、Register(注册中心)拆开,天然支持按 group、client_id、uid 推送
通过内部通信触发外部推送
实际业务中,消息往往来自数据库变更、API 调用、定时任务等“非连接事件”。这时不能靠客户端请求来驱动,需引入内部通信机制:
- 在业务代码(如 ThinkPHP 控制器、Laravel Job)中,不直接操作连接,而是向 Workerman 内部监听的端口(如 TCP 2347)发送一条结构化指令,例如:
{"action":"push","to_group":"order_notify","data":{"order_id":123,"status":"paid"}} - 另起一个独立的 Worker 监听该端口,收到后解析指令,再调用
Gateway::sendToGroup()或Gateway::sendToUid()完成真实推送 - 这种方式解耦了业务逻辑与连接管理,避免在高并发接口里做耗时的连接遍历操作
结合消息队列提升可靠性
当推送量大、网络不稳定或需重试保障时,纯内存广播可能丢消息。可接入 Redis 或 AMQP 类消息队列:
- 业务侧将推送任务写入 Redis List 或 Pub/Sub 通道,例如:
LPUSH push_queue '{"uid":1001,"msg":"新订单"}' - 由专门的 Workerman Worker 消费队列(用
Redis::lpop()或Redis::subscribe()),拿到任务后再执行 Gateway 推送 - 消费失败可延时重入队列,支持幂等处理和失败告警
注意连接与状态管理细节
很多推送失效问题其实出在连接维护上,不是框架不行,而是没管好“人”:
- 务必实现心跳保活(
onWebSocketConnect后启动Timer::add()定期 ping/pong),否则 Nginx、云厂商 SLB 会在 60–300 秒后静默断连 - 用户登录后,用
Gateway::bindUid($connection->id, $uid)绑定身份;登出时调Gateway::unbindUid($uid),避免消息错推 - 上线前检查服务器 ulimit、防火墙、安全组是否放行对应端口,生产环境别用
0.0.0.0:2346,应限定内网 IP 或加反向代理
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











