要在workerman中实现一条消息同时推送给多个指定用户,关键在于建立可查可控的用户连接映射关系,并避免跨进程通信失效问题;需在onconnect时绑定user_id与connection,在onclose时及时清理映射,推送时遍历目标uid列表或用array_filter+array_map筛选发送,多进程下须借助gatewayworker或redis+channel实现集群广播。

要在Workerman中实现一条消息同时推送给多个指定用户,关键在于建立可查可控的用户连接映射关系,并避免跨进程通信失效问题。
建立用户ID与连接的映射关系
客户端首次连接后,必须主动上报其业务唯一标识(如user_id、device_id),服务端将其与当前$connection绑定并存入全局数组。
在onMessage回调中解析客户端发来的JSON数据,提取uid字段 → 判断该uid是否已存在映射 → 若不存在,则执行 $this->uidConnections[$uid] = $connection;若已存在,可选择覆盖或拒绝重复登录。
【务必在onClose回调中删除对应uid映射】,否则断线后仍能命中旧连接导致send失败或报错。
向多个指定用户批量推送
方法一:遍历UID列表逐个发送
准备一个目标UID数组,例如 $targetUids = ['u1001', 'u1002', 'u1005'] → 循环该数组,对每个 $uid 检查 isset($this->uidConnections[$uid]) → 成立则调用 $this->uidConnections[$uid]->send($message)。
方法二:使用array_filter + array_map组合推送
这一步操作起来很简单,直接写一行:array_map(fn($c) => $c->send($message), array_filter($this->uidConnections, fn($c, $uid) => in_array($uid, $targetUids), ARRAY_FILTER_USE_BOTH));但要注意PHP版本需≥7.4,且不处理连接已断开的情况。
安全广播给在线全体用户
第一步:获取当前所有活跃连接实例
使用 $worker->connections 获取全部连接对象,这是一个关联数组,键为connection_id,值为TcpConnection实例。
第二步:过滤掉无效连接
某些连接可能已关闭但尚未被Workerman自动清理,需手动判断:foreach ($worker->connections as $conn) { if ($conn->isConnected()) { $conn->send($message); } }。
第三步:注意多进程限制
【单进程模式下才能直接遍历$worker->connections】,多进程时每个worker只持有本进程内的连接,无法触达其它进程的客户端。如需集群广播,请改用GatewayWorker或引入Redis+Channel做进程间消息中转。











