workerman中按用户分组推送需绑定稳定业务id(如user_id)到连接实例,并在断开时清理映射;推荐用gatewayworker的joingroup/sendtogroup实现可靠分组管理,或通过channel跨进程协调。

要在Workerman中实现按用户分组推送消息,必须让服务端能识别每个连接所属的业务分组(如部门ID、项目组、聊天室ID),并确保断线重连后仍能归属原分组。纯靠connection_id无法维持分组关系,因为它是每次连接随机生成的临时标识。
绑定用户ID与连接实例
客户端首次连接成功后,立即发送包含业务唯一标识(如user_id或group_id)的登录包,服务端收到后将其与当前$connection绑定并存入全局数组。
在Worker的onMessage回调中解析JSON数据:
```php
if ($data->type === 'login' && isset($data->user_id)) {
$uid = (int)$data->user_id;
$this->uidConnections[$uid] = $connection;
$connection->uid = $uid;
}
这一步必须做,否则后续无法按user_id精准触达。注意【$uid必须是整型或字符串形式的稳定业务ID,不能用session_id或token等易变值】。
连接断开时清理映射关系,防止内存泄漏:
```php
$worker->onClose = function($connection) {
if (isset($connection->uid)) {
unset($this->uidConnections[$connection->uid]);
}
};
使用GatewayWorker实现分组管理
GatewayWorker自带群组机制,比手动维护数组更可靠,适合中大型项目。
方法一:通过GatewayClient绑定用户到分组
在Web端完成登录后,调用PHP后端接口执行:
```php
use GatewayWorker\Lib\Gateway;
Gateway::joinGroup($client_id, $group_id);
其中$client_id由前端WebSocket连接建立后自动获得,$group_id是你业务定义的分组标识(例如“tech_department”或“project_2026_q3”)。
方法二:服务端主动触发分组推送
当需要向某分组广播时,在任意PHP脚本中调用:
```php
Gateway::sendToGroup($group_id, json_encode(['msg' => '任务已分配']));
【务必确认Gateway进程正在运行且group_id拼写完全一致,大小写敏感】。
基于Channel实现跨进程分组推送
适用于单Worker多进程部署场景,需额外启动Channel服务协调各Worker进程间通信。
第一步:启动Channel服务端
```bash
php start.php start -d --channel
第二步:Worker进程中监听分组事件
```php
Channel\Client::on('send_to_group', function($event_data) {
$group_id = $event_data['group_id'];
$message = $event_data['message'];
global $group_con_map;
if (isset($group_con_map[$group_id])) {
foreach ($group_con_map[$group_id] as $con) {
$con->send($message);
}
}
});
第三步:客户端发指令加入分组
发送JSON:{"cmd":"add_group","group_id":"sales_team"}
第四步:业务侧触发广播
发送JSON:{"cmd":"send_to_group","group_id":"sales_team","message":"今日KPI更新"}











