4.9 KiB
4.9 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Console Redis 在线推送 | 不建议在 slot_game 新增「用户是否在线」接口;邀请成功弹窗的在线判断应放在 slot_console,复用 EventBus 已维护的 Redis 在线集合,在 PendingPopupService 入队后「在线才 WS 即时推送、离线靠 HomeEvent 补弹」。 |
|
false |
在线判断方案:不建议 slot_game,采用 slot_console Redis
结论(对你问题的直接回答)
不建议在 slot_game 新增控制器做在线判断。
| 服务 | 职责 | 是否适合判断「大厅弹窗在线」 |
|---|---|---|
| slot_game | 游戏 WebSocket 网关(spin/bet/进游戏) | 否 — 用户在大厅连的是 slot_hub,不一定连 slot_game |
| slot_hub | 大厅 WS + Gateway::isUidOnline($uid)(见 BaseLogic) |
最准,但需跨服务 HTTP/RPC,07 文档一期未接 |
| slot_console | 弹窗入队、EventBus 维护 Redis 在线集合 | 合适 — 数据已有,无跨服务调用 |
当前邀请成功链路(已实现):
sequenceDiagram
participant Logic as LuckyRewardInviteLogic
participant Popup as PendingPopupService
participant Redis as Redis_online_set
participant WS as WsService_MQ
participant Home as HomeEvent
Logic->>Popup: enqueue 邀请人弹窗
Popup->>Popup: 写 user_pending_popup
Popup->>WS: notifyClientPOP(当前始终发送)
Note over Home: 离线/游戏中靠 home flush 补弹
你已选择 slot_console + Redis 方案:与 07 待弹窗方案 一致 — 持久化必做,WS 仅 best-effort。
推荐实现(小改动,不改 slot_game)
1. 封装在线查询(slot_console)
在 RedisKeyManagerService 或新建 UserOnlineService(公共能力,非 Logic 型业务编排):
public static function isUserOnline(int $uid): bool
{
if ($uid <= 0) {
return false;
}
return (bool) Redis::sIsMember(self::getUserOnlineKey(), (string) $uid);
}
数据来源:EventBus::websocketConnectEvent / websocketUnconnectEvent 已对 getUserOnlineKey() 做 sAdd / sRem。
语义说明:Redis 在线 = 有 WebSocket 连接,不等于「一定在大厅」;游戏内是否弹仍由客户端忽略 WS + HomeEvent 仅非 enter_game 时 flush 保证(PRD 4.2)。
2. 调整 PendingPopupService::enqueue
- 不变:幂等写
user_pending_popup(离线也必须写,否则丢通知) - 变更:仅当
isUserOnline($uid)为 true 时调用WsService::notifyClientPOP - 离线:跳过 WS,等
HomeEvent::appendLuckyRewardHomePopups补弹
if (UserOnlineService::isUserOnline($enqueueDto->uid)) {
WsService::notifyClientPOP(...);
}
此改动作用于所有走 PendingPopupService 的定向弹窗(含邀请成功 lucky_reward_invite_success),符合 F 通用机制。
3. 测试
- 单元测:
isUserOnline对 Redis mock 或集成测 sAdd/sIsMember - 可选:集成测 invite_bind 成功后 pending 记录存在;在线/离线 WS 行为(若难 mock MQ,至少单测 PendingPopupService 分支)
4. 文档
- 07 用户定向弹窗通知机制方案 §4
enqueue说明补一句:即时 WS 仅在 Redis 在线集合命中时发送 LuckyRewardInviteLogic的notifyInviterInviteSuccessPHPDoc 注明依赖 PendingPopupService 在线 gate,Logic 内不再单独查在线
若将来需要 HTTP「查在线」给其他服务
- 优先 slot_console
innerapi(如GET /innerapi/user/is-online?uid=),读同一 Redis 集合 - 或 slot_hub innerapi 调
Gateway::isUidOnline(需 GatewayClient 配置,跨进程) - 仍不建议 slot_game — 除非明确要查「是否在游戏 WS 连接中」(与大厅弹窗无关)
不在本次范围
- slot_game 新 Controller
- slot_hub Gateway 跨服务封装(除非 Redis 与 Gateway 长期不一致再评估)
- 区分「大厅 vs 游戏中」的服务端精确状态(仍靠客户端 + HomeEvent
from)