fix: add WebSocket keepalive to prevent CDP connection drops on remote browsers (#936)

The v0.20.0 Rust rewrite dropped two keepalive mechanisms that the
Node.js/Playwright daemon provided, causing CDP connections to remote
Browserless instances to silently die between commands when traversing
multi-hop proxy topologies (Istio Envoy, OpenResty, etc.).

Restore parity with v0.19.0 and improve on it:

1. TCP SO_KEEPALIVE (v0.19.0 parity): Playwright's WebSocketTransport
   used HTTP agents with keepAlive: true, which set SO_KEEPALIVE on the
   underlying TCP socket. Restored via socket2::SockRef on the
   tokio_tungstenite stream before splitting.

2. WebSocket Ping frames (improvement): Send Ping frames every 30s on
   idle connections. This goes beyond v0.19.0 because L7 proxies (Envoy,
   nginx, OpenResty) can see WebSocket pings but not TCP keepalive
   probes, making this effective through application-layer proxy hops.

The keepalive task is coordinated with the reader loop via a watch
channel and stops automatically when the connection closes.

Fixes #934

Co-authored-by: ctate <366502+ctate@users.noreply.github.com>
This commit is contained in:
Chris Tate
2026-03-19 19:12:57 -05:00
committed by GitHub
co-authored by ctate
parent 2b3c5c26cd
commit 421f8fab82
3 changed files with 64 additions and 0 deletions
+1
View File
@@ -60,6 +60,7 @@ dependencies = [
"serde_json",
"sha2",
"similar",
"socket2",
"time",
"tokio",
"tokio-tungstenite",