必须建立房间与连接的映射关系,否则无法精准推送;通过onConnect分配默认房间、onMessage处理join请求切换房间、onClose清理残留引用;广播时遍历目标房间连接数组并发送JSON消息。

要在 Workerman 中实现向指定房间内所有在线用户推送消息,必须先建立房间与连接的映射关系,否则无法识别“谁在哪个房间”。直接遍历全部连接会发错人,漏发或误发都可能发生。
服务端建立房间连接映射
第一步:在 $worker->onConnect 回调中,为每个新连接分配一个初始房间标识(如默认房间 'lobby'),并存入全局房间数组。
$worker->onConnect = function($connection) use (&$rooms) {<br> $connection->room = 'lobby';<br> $rooms['lobby'][$connection->id] = $connection;<br>};
第二步:接收客户端发来的加入房间请求,解析 JSON 消息,验证 type === 'join' 且 room 字段存在,然后将该连接从旧房间移出、加入新房间。
第三步:在 $worker->onClose 中主动清理该连接在所有房间中的残留引用,避免内存泄漏和向已断开连接发送失败。
向指定房间所有人广播消息
方法一:使用房间映射表直接遍历发送
构造消息结构体,例如:$msg = ['type' => 'room_broadcast', 'room' => 'admin', 'content' => '系统通知:维护开始'];
获取目标房间的所有活跃连接:$targetRoom = $rooms['admin'] ?? [];
遍历发送:foreach ($targetRoom as $conn) { $conn->send(json_encode($msg)); }
【注意:$rooms['admin'] 是引用数组,不是副本;若在遍历时有连接断开,可能导致 foreach 报 Warning 或跳过部分连接】
前端触发加入房间并接收消息
页面加载后立即建立 WebSocket 连接:
const ws = new WebSocket('ws://your-domain:2345');
连接就绪后,主动发送加入指定房间指令:
ws.onopen = () => {<br> ws.send(JSON.stringify({ type: 'join', room: 'support_001' }));<br>};
监听服务端推送的消息,只处理 room_broadcast 类型且 room 匹配当前所在房间的消息:
ws.onmessage = (e) => {<br> const data = JSON.parse(e.data);<br> if (data.type === 'room_broadcast' && data.room === currentRoom) {<br> showNotification(data.content);<br> }<br>};

















