必须绑定用户ID与客户端连接才能精准私聊,即登录时校验uid并存入$user_connections[$uid]=$client_id,推送时通过$client_id或映射表发送;未绑定则静默失败;前端需解析type字段区分私聊。

要让Workerman后端主动向指定用户发送私聊消息,而不是群发或广播,必须确保每个客户端连接与业务系统中的用户ID完成双向绑定,且推送时能精准定位到该用户的WebSocket连接对象。
绑定用户ID与客户端连接
在客户端首次建立WebSocket连接并完成身份验证后,立即将业务系统的用户ID(如数据库中的uid)与Workerman分配的$client_id关联起来。
修改onMessage回调,接收登录请求并写入全局映射数组:
第一步:接收前端传来的登录数据,格式为{"type":"login","uid":1001};
第二步:校验uid合法性(例如查数据库是否存在该用户),失败则关闭连接;
第三步:将$client_id存入$user_connections[$uid] = $client_id;
这一步不可跳过,否则后续无法根据uid找到对应连接。若未绑定就尝试推送,【推送会静默失败,无报错也无日志】。
主动向指定用户推送消息
当业务逻辑需要向某用户发私信(比如客服分配、订单状态变更),直接调用Workerman内置方法向其绑定的连接发送数据。
方法一:使用GatewayWorker方式(推荐用于中大型项目)
调用Gateway::sendToClient($client_id, $message),其中$client_id来自上一步绑定的映射表;
方法二:纯Workerman方式(适合轻量级一对一场景)
遍历保存的连接映射:if (isset($user_connections[$target_uid]) && $user_connections[$target_uid] instanceof TcpConnection) { $user_connections[$target_uid]->send($message); };
注意:不能直接用Gateway::sendToUid(),除非你已启用GatewayWorker并配置了registerAddress和businessWorker进程,否则该方法不存在。
前端接收并解析私聊消息
客户端WebSocket收到消息后,需判断是否为私聊类型,再决定如何展示。
监听ws.onmessage,对e.data做JSON解析;
检查result.type === 'private'且result.from_uid为你当前会话对象;
若匹配成功,则将result.content追加到对应聊天窗口DOM中;
这一步不做类型判断,所有消息都会混在一起显示,无法区分是群聊还是私聊。

















