workerman实现websocket长连接异步推送的核心是独立websocket进程+channel跨进程通信+客户端uid绑定:需在config/process.php注册ws进程,用channel订阅/发布消息,连接时解析并存储uid至redis映射表,配合心跳保活与异常清理保障稳定。

Workerman 实现 WebSocket 长连接异步推送,核心在于维持前端持久连接 + 后端解耦通知 + 主动触发广播。它不依赖轮询或刷新,而是让服务端在数据变化时“主动喊一声”,前端立刻响应。整个过程无需阻塞主业务逻辑,天然支持高并发。
WebSocket 服务端基础搭建
用 Workerman 启一个常驻的 WebSocket 服务,是所有推送的前提:
- 创建 Worker 实例,协议指定为
websocket://0.0.0.0:2000(端口可自定义) - 设置进程数(如
$worker->count = 4),提升并发承载力 - 注册
onConnect、onMessage、onClose回调,管理连接生命周期 - 调用
Worker::runAll()启动服务,保持常驻运行(加-d参数后台守护)
客户端连接与身份标识
前端通过原生 WebSocket 或小程序 wx.connectSocket 连接,关键点在于绑定唯一标识:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 连接建立后,建议让前端立即发送用户 ID(如 openid、uid、token 解析出的 user_id)
- 服务端在
onMessage中解析并存入内存(如$connection->uid = $uid),或关联到 Redis 的在线用户表 - 后续推送时,就能按需单推(指定 uid)、群推(某角色/房间)、或广播(全部)
异步推送的关键:解耦业务与通知
不能在数据库写入后直接调用 $connection->send()——因为此时可能不在 WebSocket 进程上下文里。正确做法是跨进程通信:
- 启动一个独立的监听进程(如 TCP 或 Unix Socket),专门接收内部通知(例如用
AsyncTcpConnection或Redis pub/sub) - 业务代码(如 Laravel 控制器、TP5 模型保存后)向该监听端口或 Redis 频道发消息,内容含目标 uid 和数据
- WebSocket 进程监听同一通道,收到后查找出对应连接,调用
$connection->send(json_encode($data)) - 若用 Redis,推荐搭配
workerman/redis异步组件,避免阻塞
保障稳定性的实用细节
真实场景中容易忽略但影响体验的点:
-
心跳保活:前端每 30–60 秒发
ping,服务端onMessage中识别并回复,防止代理或 NAT 断连 -
连接异常处理:在
onClose和onError中清理内存中的连接引用,避免内存泄漏 -
消息序列化安全:推送前用
json_encode($data, JSON_UNESCAPED_UNICODE),避免中文乱码或特殊字符截断 -
SSL 支持(WSS):生产环境必须启用,只需增加
'transport' => 'ssl'并配置证书路径










