fix: Chats doesn't sync for multi client users

This commit is contained in:
2026-06-11 00:04:49 +02:00
parent d0aff6319d
commit d174536272
16 changed files with 662 additions and 16 deletions

View File

@@ -54,6 +54,7 @@ Require `Authorization: Bearer`:
- `oderId` must match the token's user id when provided.
- `clientInstanceId` is a stable per-tab UUID generated by the product client (`metoyou.clientInstanceId` in `sessionStorage`). The signaling server uses it to distinguish multiple WebSocket connections for the same user and to route voice ownership.
- Server responds with `auth_error` or `auth_required` when authentication fails.
- **Per-connection message ordering (invariant):** the server processes WebSocket messages for one connection strictly in arrival order (`handleWebSocketMessage` chains them per connection id). `identify` awaits a DB token lookup, and clients send `identify` + `join_server` back-to-back (often one TCP segment); concurrent handling let the join run mid-identify, get rejected as unauthenticated, and silently drop room membership — that connection then missed all `user_joined` / `chat_message` broadcasts (root cause of "chats don't sync for multi-client users").
## Multi-device sessions
@@ -68,7 +69,8 @@ When the same account is logged in on multiple devices, account-owned data is ke
| Data | Mechanism |
|---|---|
| Server chat messages | Existing `chat_message` relay (connection-scoped broadcast) |
| Server chat messages (live) | `chat_message` signaling relay (connection-scoped broadcast) **plus** `account_sync` `chat-message` / `message-revision` to sibling devices |
| Server chat messages (catch-up) | `account_sync` `chat-sync-batch` pushed when a sibling device comes online (`account_sync_peer_online`) |
| Voice / typing | Existing `voice_state` / `user_typing` relays |
| Saved servers (join/leave) | `account_sync` payload `saved-room-sync` / `saved-room-remove` |
| Profile avatar + card text | `account_sync` `user-avatar-full` + `user-avatar-chunk` |
@@ -81,7 +83,7 @@ Client rules:
- `broadcastMessage()` still fans out over peer data channels; relayable events are **also** wrapped in `account_sync` and sent on the WebSocket.
- The server forwards `account_sync` to every other open connection for the same `oderId` via `notifyOtherConnectionsForOderId`.
- Receivers ignore payloads whose `clientInstanceId` matches the local tab id.
- When a new device identifies, the server notifies existing connections with `account_sync_peer_online`; those devices push a full snapshot (saved rooms, friends, profile, emoji library).
- When a new device identifies, the server notifies existing connections with `account_sync_peer_online`; those devices push a full snapshot (saved rooms, **room message history**, friends, profile, emoji library).
WebSocket envelope: