OpenAI ★★ Frequent Medium-Hard WebSocketPub/SubRoom State

O21 · Design a Chat Room O21 · 设计聊天室

Verified source经核实出处

Listed in 小红书 @Infra+RL+Robots recruiter post (2026) as one of OpenAI's 5 SD-pool questions. Distinct from O4 (Design Slack) — a Chat Room has a single logical room with many members, no DMs / workspaces / threads. Credibility B.来自小红书 @Infra+RL+Robots 招聘官(2026)列出的 OpenAI 五大 SD 题池之一。与 O4(Slack)不同——聊天室是单一逻辑房间多成员,不含 DM / 工作区 / Thread。可信度 B

Scoping: Chat Room ≠ Slack范围:聊天室 ≠ Slack

CapabilityChat Room (O21)Slack (O4)
Room structureSingle room id, broadcast to all joined members.单房间 id,广播给所有加入成员。Workspaces → channels → threads → DMs.工作区 → 频道 → Thread → DM。
HistoryBounded or session-based; some variants are ephemeral.有界或 session 内;部分变体瞬时。Permanent, searchable, paginated.永久保存、可搜索、分页。
OrderingPer-room monotonic seq.每房间单调递增 seq。Per-channel seq.每频道 seq。
PresenceActive member list, typing indicators.在线成员列表、正在输入指示。User-global presence (online/away).用户全局在线状态(在线/离开)。

Architecture架构

flowchart LR
  C1[Client A] & C2[Client B] --> LB[WS Load Balancer
sticky by room_id] LB --> WS1[WS Gateway 1] LB --> WS2[WS Gateway 2] WS1 & WS2 --> RC[Room Coordinator
Redis pub/sub] WS1 & WS2 --> MSG[Message Service] MSG --> DB[(Messages: room_id, seq, payload)] MSG --> SEQ[Seq Generator
Redis INCR per room] WS1 --> PRES[Presence Service
Redis TTL]

Message flow (hot path)消息流(热路径)

  1. Client sends over existing WS: {type:"msg", room_id, client_msg_id, text}.客户端通过已有 WS 发送 {type:"msg", room_id, client_msg_id, text}
  2. Gateway dedups on client_msg_id, calls Message Service.网关按 client_msg_id 去重,调用 Message Service。
  3. Message Service assigns seq = INCR room:{id}:seq, persists, then publishes to room:{id} channel.Message Service 通过 INCR room:{id}:seq 分配 seq,持久化后发布到 room:{id} 频道。
  4. All WS gateways subscribing to that channel push to local clients.所有订阅该频道的 WS 网关将消息推送到本地客户端。

Connection & room state连接与房间状态

  • Sticky routing: hash room_id → a shard of WS gateways → keeps pub/sub fan-out local.粘性路由room_id 哈希 → 一组 WS 网关 → 保持 pub/sub 本地 fan-out。
  • Join/Leave: WS gateway maintains Map<room_id, Set<conn>>; on join, subscribe to Redis channel; on last-leaver, unsubscribe.加入/离开:WS 网关维护 Map<room_id, Set<conn>>;加入时订阅 Redis 频道;最后一人离开时退订。
  • Reconnect: client sends last_seq; server ships missed messages then subscribes stream.重连:客户端带 last_seq;服务端补发 + 订阅流。

Follow-ups追问

  • 10K-member room fan-out storm? Shard the room across multiple pub/sub channels; or switch to a dedicated "mega-room" service that buffers and batches pushes.1 万人大房间 fan-out 风暴?把房间拆到多个 pub/sub 子频道;或切到专用「超级房间」服务做缓冲批量推送。
  • Typing indicators at scale? Not persisted; rate-limited (e.g., 1 "typing" event per 3 s per user); use a separate ephemeral pub/sub topic.大规模正在输入?不持久化;限流(每用户每 3 秒 1 次);用独立的瞬时 pub/sub 主题。
  • Moderation? Synchronous blocklist/regex check inline; async classifier after; client can render a "pending-review" placeholder.内容审核?同步 blocklist/正则;异步分类器;客户端渲染「审核中」占位。
  • End-to-end encryption? Signal-like; server stores ciphertext + metadata only; but room join needs key rotation on member change.端到端加密?Signal 风格;服务端仅存密文 + 元数据;成员变更时需密钥轮换。

Related study-guide topics相关学习手册专题