Skip to content

Enable TCP keepalive on client socket - #63

Open
TooAngel wants to merge 1 commit into
thibauts:masterfrom
TooAngel:enable-tcp-keepalive
Open

Enable TCP keepalive on client socket#63
TooAngel wants to merge 1 commit into
thibauts:masterfrom
TooAngel:enable-tcp-keepalive

Conversation

@TooAngel

@TooAngel TooAngel commented Aug 14, 2026

Copy link
Copy Markdown

Problem

Chromecasts silently drop idle TCP connections — no FIN, no RST. The client's tls.connect socket doesn't have SO_KEEPALIVE enabled, so the OS never probes the peer, and a dead socket looks alive.

Symptom: after some idle period, the next send() writes into a socket that will never be read. Node reports success (the kernel buffer accepts the bytes), but nothing gets through. The application-layer heartbeat in node-castv2-client is supposed to detect this via missing PONGs, but does not fire reliably — see the long-standing thibauts/node-castv2-client#44. Callers end up hanging on their own timeouts.

Fix

One line: enable SO_KEEPALIVE on the TLS socket with a 10 s initial delay. When the socket is genuinely idle for that long, the OS starts sending keepalive probes; if the peer is gone, the OS closes the socket and Node emits close — which the existing onclose handler already handles.

this.socket.setKeepAlive(true, 10000);

Why it's safe

  • Additive only. No existing code path is changed.
  • During any active session, application traffic (heartbeat PING every 5 s, plus normal messages) keeps the socket busy — the OS never reaches the idle threshold, so keepalive probes are never sent.
  • Only fires when the connection has been genuinely idle at the TCP level for ~10 s, which is precisely the failure mode we want to catch.
  • Standard Node.js API; no new dependencies.

Verified against

Real Chromecast (Blaupunkt PMR100-style receiver). Before the change, first player.load after >5 min of idle hung for 8 s until the caller's timeout fired, then retried. After the change (patched at the consumer level as a preview), no hang and no retry needed.

Chromecasts silently drop idle connections. Without SO_KEEPALIVE the
OS never probes, and the next write hangs until the caller's own
timeout fires. setKeepAlive(true, 10000) lets the OS detect dead
peers after ~10s of TCP-level idle.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant