Files
cursor/plans/console_redis_在线推送_cf0daa26.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

4.9 KiB
Raw Permalink Blame History

name, overview, todos, isProject
name overview todos isProject
Console Redis 在线推送 不建议在 slot_game 新增「用户是否在线」接口;邀请成功弹窗的在线判断应放在 slot_console复用 EventBus 已维护的 Redis 在线集合,在 PendingPopupService 入队后「在线才 WS 即时推送、离线靠 HomeEvent 补弹」。
id content status
user-online-service 新增 UserOnlineService::isUserOnline读 Redis getUserOnlineKey+ 单测 completed
id content status
pending-popup-online-gate PendingPopupService::enqueue 在线才 notifyClientPOP离线仅持久化 completed
id content status
docs-verify-online 更新 07 文档 enqueue 说明;跑 verify + 相关单测 in_progress
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/RPC07 文档一期未接
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
  • 离线:跳过 WSHomeEvent::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. 文档


若将来需要 HTTP「查在线」给其他服务

  • 优先 slot_console innerapi(如 GET /innerapi/user/is-online?uid=),读同一 Redis 集合
  • slot_hub innerapiGateway::isUidOnline(需 GatewayClient 配置,跨进程)
  • 仍不建议 slot_game — 除非明确要查「是否在游戏 WS 连接中」(与大厅弹窗无关)

不在本次范围

  • slot_game 新 Controller
  • slot_hub Gateway 跨服务封装(除非 Redis 与 Gateway 长期不一致再评估)
  • 区分「大厅 vs 游戏中」的服务端精确状态(仍靠客户端 + HomeEvent from