Skip to content

Add PING/PONG protocol actions and heartbeats=bounce (RTN23c) - #522

Open
SimonWoolf wants to merge 3 commits into
mainfrom
heartbeats-ping-pong
Open

SimonWoolf wants to merge 3 commits into
mainfrom
heartbeats-ping-pong

Conversation

@SimonWoolf

Copy link
Copy Markdown
Member

Problem

Browsers may freeze background tabs (see Chrome's energy-saver freezing). A frozen tab's websocket continues to answer transport-level ping frames on the page's behalf while none of the page's own code can run. Since the server determines liveness from the websocket pong, it never detects the client as gone: presence members are not removed, and so on, even though the session is effectively dead.

Change

  • New PING (22) and PONG (23) ProtocolMessage actions (TR2, IDL, protocol.md).
  • New heartbeats=bounce value (RTN23b, RTN23c). In this mode the server sends PINGs instead of HEARTBEATs to satisfy maxIdleInterval, and closes the transport if the client does not answer with a PONG. Browser clients should send this.
  • RTN23c1/RTN23c2: every client must answer a PING with a PONG on the same transport, echoing the PING's id, regardless of which heartbeats value it sent. This is unconditional so the param is purely the client's request for the server to use this mechanism.
  • CD2h mentions the new action.
  • UTS: tests for the bounce query param, PONG echoing id, PONG regardless of heartbeats param, and PING resetting the idle timer.
  • Also adds the missing ANNOTATION member to the IDL ProtocolMessageAction enum.
  • Bumps specification version to 6.2.0.

Connection#ping (RTN13) is deliberately left on HEARTBEAT; dedicated PING/PONG avoid the request/response ambiguity (and hence ping-pong loop risk) that reusing HEARTBEAT for server-initiated liveness checks would introduce.

🤖 Generated with Claude Code

SimonWoolf and others added 3 commits September 15, 2026 21:19
TR2 lists it but the IDL enum stopped at OBJECT_SYNC.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Browsers may freeze background tabs. A frozen tab's websocket continues to
answer transport-level ping frames on the page's behalf while none of the
page's own code can run, so the server does not detect the client as gone
and, for example, its presence members are never removed.

heartbeats=bounce asks the server to check liveness at the protocol level
instead: it sends PING ProtocolMessages and closes the transport if the
client does not answer with a PONG. The client's obligation to answer a PING
with a PONG (RTN23c1) is unconditional, so the param is purely the client's
request for the server to use this mechanism.

Connection#ping (RTN13) is left on HEARTBEAT.

Bumps specification version to 6.2.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants