fix(cast): heartbeat the Chromecast every 5s to keep the connection alive

Google Cast closes a control connection that goes roughly 10 seconds without a heartbeat PING. QBZ pinged every 25 seconds, so any cast connection left idle between connect and load — for example while the track downloads, or across a delayed second play attempt — was dropped by the receiver. The next LOAD then failed with EPIPE (broken pipe): the device chimed on connect but never played audio, and the heartbeat thread logged repeating broken-pipe warnings.

Pinging every 5s is the cadence the Cast protocol expects and keeps the connection alive through those idle gaps.

Fixes #439.

cc
This commit is contained in:
vicrodh committed 2026-05-16 14:38:29 -06:00
1 parent bf734546d1
commit bfcd769055
1 file changed
+6 -1
+6 -1
View File
@@ -216,7 +216,12 @@ impl Drop for ChromecastHandle {
}
}
const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(25);
// Google Cast drops a control connection that goes roughly 10s without a
// heartbeat PING. Ping every 5s — the cadence the protocol expects — so a
// cast connection left idle between connect and load (e.g. while a track
// downloads) is not closed by the receiver. A 25s interval left idle
// connections dead, surfacing as EPIPE on the next LOAD (issue #439).
const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5);
/// Main loop for the Chromecast thread
fn chromecast_thread_main(receiver: Receiver<CastCommand>) {