Skip to content

feat: add ping/pong heartbeat to WebSocket connections#42

Merged
Ark0N merged 1 commit intofeat/ws-terminal-io-upstreamfrom
feat/ws-heartbeat
Mar 14, 2026
Merged

feat: add ping/pong heartbeat to WebSocket connections#42
Ark0N merged 1 commit intofeat/ws-terminal-io-upstreamfrom
feat/ws-heartbeat

Conversation

@Ark0N
Copy link
Copy Markdown
Owner

@Ark0N Ark0N commented Mar 14, 2026

Summary

  • Adds server-side ping/pong heartbeat (30s interval, 10s pong timeout) to WebSocket terminal connections
  • Detects and terminates stale connections that TCP keepalive won't catch for minutes, especially through tunnels/proxies
  • All timers (ping interval, pong timeout) are cleaned up in the close handler to prevent leaks

Details

The ws library's built-in ping()/on('pong') methods are used. Browser WebSocket clients respond to pings automatically at the protocol level — no client-side changes needed.

Each ping cycle:

  1. Sets alive = false, sends a ping frame, starts a 10s pong timeout
  2. If pong arrives: marks alive = true, clears the timeout
  3. If pong timeout fires or next ping finds alive still false: socket.terminate()

Test plan

  • npx tsc --noEmit passes (verified)
  • Manual test: connect via WS, observe ping frames in browser devtools Network > WS tab
  • Manual test: suspend network on client side, confirm server terminates after ~40s

🤖 Generated with Claude Code

Detect stale connections that TCP keepalive won't catch for minutes,
especially through tunnels and proxies. Pings every 30s with a 10s
pong timeout — if the client doesn't respond, the socket is terminated
and all timers cleaned up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Ark0N Ark0N merged commit 3a41de7 into feat/ws-terminal-io-upstream Mar 14, 2026
1 check passed
SGudbrandsson pushed a commit to SGudbrandsson/Codeman that referenced this pull request Mar 23, 2026
The server was dropping the `data` field from hook-event POST requests,
so notifications always showed generic messages. Now forwards tool name,
command, question text, and reason to the frontend.

Notifications now show:
- permission_prompt: "Bash: docker push prod:latest"
- elicitation_dialog: "Merge PR Ark0N#42 to main?"
- idle_prompt: custom message if provided
- stop: reason if provided

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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