feat: signal server tag

This commit is contained in:
2026-06-05 06:16:02 +02:00
parent 6865147e8f
commit bf4e6891d1
69 changed files with 2808 additions and 1269 deletions

View File

@@ -158,7 +158,7 @@ sequenceDiagram
### Reconnection
When the WebSocket drops, `SignalingManager` schedules reconnection with exponential backoff (1s, 2s, 4s, ... up to 30s). On reconnect it replays the cached `identify` and `join_server` messages so presence is restored without the UI doing anything.
When the WebSocket drops, `SignalingManager` schedules reconnection with exponential backoff (1s, 2s, 4s, ... up to 30s). Each connect attempt is bounded by `SIGNALING_CONNECT_TIMEOUT_MS` (5s); stale sockets stuck in `CONNECTING` are discarded so retries keep running while the server is down. The local dev server and current production builds answer application keepalives with `keepalive_ack`; once a server has answered at least one keepalive the client enforces the ack timeout so half-open sockets do not linger after a process restart. The first keepalive and HTTP health probe run on the first heartbeat tick after connect (not after the full 25s keepalive interval), so localhost restarts are detected in roughly 515s instead of waiting for the periodic keepalive cadence. While a socket appears open the client also probes `/api/health` every `SIGNALING_HEALTH_PROBE_INTERVAL_MS` (5s); failed probes, health recovery after an outage, or a changed `serverInstanceId` all force a fresh websocket so zombie connections after a process restart cannot keep stale presence. Failed outbound sends still force a reconnect. On reconnect it replays the cached `identify` and `join_server` messages so presence is restored without the UI doing anything, and `RoomsEffects.resyncRoomsOnSignalingReconnect$` re-runs the room join flow as a safety net.
The browser also sends a lightweight `keepalive` message on the signaling socket during long-lived sessions. The server treats both WebSocket pong frames and any inbound client message as liveness, so users who are still active in voice or chat are not removed from server presence just because control-frame pong delivery stalls behind a proxy or runtime quirk.