跳轉到

D-20260802-01|RoomId=不可重用的房間實例識別

背景與驅動力

既有六碼房號只有 34^6 個組合,並以非密碼學 Math.random() 產生;它同時充當房間實例識別、Gossip key、signaling scope、觀戰入口與 URL。短碼可重用使延遲訊息、舊連結與新房間落在同一 namespace,不能穩定區分兩次不同的房間生命週期。

考慮過的選項

  • 保留六碼並增加中央租約:需要引入全域協調者,違反 P2P 房間發現設計。
  • 六碼作為 canonical id、另加 generation:所有 wire 與 URL 仍需攜帶兩欄,且舊碼單獨流通時仍有歧義。
  • UUID v4 作為 canonical RoomId(採納):由 Web Crypto 產生,122 bits 隨機性,格式與驗證跨端一致。

決定

  • RoomId 是 branded string,canonical wire 形式為小寫 UUID v4;生成使用 crypto.randomUUID(),碰到仍存活的極低機率衝突時重生。
  • 每次建房都產生新 RoomId;關房後不得刻意重用。RoomId 貫穿 room state、Gossip discovery/presence、match offer、signaling room:<roomId> scope、觀戰、聊天、摘要與 /room/:roomId
  • 所有不可信邊界以同一 parser fail-closed;舊 roomCode 欄位與六碼值不接受、不保留相容讀取或雙寫。
  • matchId 仍依 D-20260710-02 由 roster、startedAt、matchRules 推導;RoomId 不加入比賽共識識別。
  • 未來若需要便於口述的邀請碼,必須建模為可輪換、可過期且與 RoomId 分離的 alias;不得重新把 alias 當房間實例識別。

後果與影響

延遲公告、舊 URL 與歷史訊息不會因短碼重用誤指向新房;P2P 各層以單一識別鍵對齊。代價是人工輸入較長,因此目前 UI 顯示「房間 ID」並接受完整 UUID;可讀邀請 alias 留給獨立需求處理。