workerman + gatewayworker 实现群发推送需明确“谁发、发给谁、怎么推”:客户端websocket连接gateway,businessworker解析type字段路由消息,通过joingroup和sendtogroup实现group级群发,并统一广播格式确保前后端协同。

Workerman + GatewayWorker 实现客户端发送消息并群发推送,核心在于区分“谁发”、“发给谁”、“怎么推”。客户端(如 Web、App)通过 GatewayWorker 的 WebSocket 连接上 Gateway,再由 Gateway 转发给 BusinessWorker 处理业务逻辑;群发则需在 BusinessWorker 中调用 GatewayClient 向指定 group 或所有 client_id 广播。
客户端连接与消息上行(发给服务端)
前端使用 WebSocket 连接到 Gateway 监听的地址(如 ws://your-domain.com:8282),发送 JSON 格式消息:
- 必须携带
type字段标识消息类型(如"type":"chat"、"type":"join_group") - 建议带上
group(群组 ID)或to(目标用户 ID),便于后端路由 - 示例:
{"type":"chat","group":"room_1001","content":"hello"}
BusinessWorker 接收并解析消息
在 Events.php 的 onMessage 回调中处理上行消息:
- 用
GatewayWorker\BusinessWorker::getUidByClientId($client_id)可查发送者身份(若已绑定 UID) - 根据
type分支处理:聊天、入群、退群等 - 关键点:群发前先确定目标范围——是整个 group?某类角色?还是在线的所有人?
精准群发:按 group / uid / client_id 推送
推荐使用 group 机制实现房间级群聊(更高效、易管理):
- 用户加入时调用
Gateway::joinGroup($client_id, $group)(如"room_1001") - 群发时直接
Gateway::sendToGroup($group, $message),自动推送给该 group 内所有在线 client - 若需按角色推送(如只发给管理员),可维护一个
admin_list = ['uid1','uid2'],再用Gateway::sendToUid($uid, $message)循环发送 - 注意:确保
Gateway::$registerAddress配置正确,且 Register 服务正在运行
消息格式与广播内容统一规范
为避免前端解析混乱,服务端推送的消息建议固定结构:
{"type":"broadcast","from_uid":123,"group":"room_1001","content":"hello","time":1715829300}- 前端监听
message事件后,用data.type判断行为,再渲染或触发逻辑 - 敏感操作(如踢人、禁言)建议加签名或权限校验,不能仅靠前端传参
不复杂但容易忽略:群发前务必确认 client_id 是否在线(Gateway::isOnline($client_id)),避免无效调用;group 名称建议用业务 ID(如订单号、房间号),别用中文或空格。











