Skip to content

fix(call): detect dead signaling WebSocket connections via ping interval - #6543

Open
tareko wants to merge 1 commit into
masterfrom
fix/websocket-keepalive
Open

fix(call): detect dead signaling WebSocket connections via ping interval#6543
tareko wants to merge 1 commit into
masterfrom
fix/websocket-keepalive

Conversation

@tareko

@tareko tareko commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

fix(call): detect dead signaling WebSocket connections via ping interval

Description

The signaling WebSocket is currently created from the shared OkHttpClient, which never sets a ping interval. In OkHttp 4.x this means no protocol-level pings are sent and the WebSocket read timeout is effectively infinite. When the underlying network dies without a TCP reset — the normal case when switching from WiFi to cellular, or when a router/NAT drops an idle mapping — the connection becomes half-open:

  • onFailure never fires (TCP retransmission timeouts can take 15+ minutes)
  • isConnected stays true, so the existing reconnect logic never runs
  • outgoing offers/answers/ICE candidates/mute state are silently lost, incoming signaling stops

The result is a "zombie" call: participants still see each other, but the call is mute/deaf. This is the root cause of the failure mode reported in #2368 and #1760 (analysis also posted on #2368).

This PR derives a dedicated client for signaling WebSocket connections with a 10 second ping interval. OkHttp now fails the socket when a pong is not received in time, which triggers the existing onFailurerestartWebSocket() path. The shared client used for regular HTTP calls is unchanged (ping intervals have no effect on non-WebSocket calls, but the dedicated instance keeps the change scoped).

Steps to reproduce / How to test

  1. Join a call using external signaling (HPB) or internal signaling
  2. Drop WiFi in a way that does not produce a TCP reset (walk out of range, reboot the router) so cellular takes over
  3. Speak / observe the call

Without this PR: the call silently stops working — no reconnect, participants appear present but nothing is transmitted, for 15+ minutes.

With this PR: within ~10–20 seconds the dead socket fails, onFailure triggers, and the existing reconnect flow runs (reconnect + hello/resume).

Also test that normal call behavior is unaffected: join/leave calls, chat while connected, both WiFi and cellular, with and without HPB.

  • ⛑️ Tests are included (unit tests pin the client configuration)
  • 🔖 Capability is checked or not needed (no capability change)
  • 🔙 Backport requests or not needed: /backport to stable-24.0 may be worthwhile given No automatic reconnect on instable connection #2368 affects older versions
  • 📅 Milestone is set
  • 🌸 PR title is meaningful

Fixes part of #2368


Note: This change was developed with AI assistance (opencode / Kimi K3 and GLM-5.3).

The signaling WebSocket was created from the shared OkHttpClient without
a ping interval. In OkHttp 4.x this means no protocol-level pings are
sent and the WebSocket read timeout is infinite, so a half-open
connection (e.g. after switching from WiFi to cellular without a TCP
reset) is never detected: onFailure never fires, the existing reconnect
logic never runs, and the call goes silently mute/deaf while
participants still appear present.

Derive a dedicated client for the signaling WebSocket that pings every
10 seconds. OkHttp now fails the socket when a pong is not received in
time, which triggers the existing onFailure -> restartWebSocket path.
Regular HTTP calls keep using the unchanged shared client.

Assisted-by: opencode:ox-alpha
Signed-off-by: Tarek Loubani <tarek@tarek.org>
@AndyScherzinger
AndyScherzinger requested a review from mahibi August 22, 2026 07:19
@AndyScherzinger AndyScherzinger added the 3. to review Waiting for reviews label Aug 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants