Problem
The WebSocket client has a heartbeat: pingIntervalMs (src/http/websocket/WebsocketClientOptions.ts:46, driven at src/http/websocket/WebsocketClientActor.ts:178-180). The server side has no equivalent: ResolvedWebsocketPolicy covers only frame size, invalid messages, backpressure and maxConnections (src/http/websocket/WebsocketPolicy.ts:19-31), and WebsocketRouteOptionsBuilder has no withHeartbeat* / withIdleTimeout* (src/http/websocket/WebsocketRouteOptions.ts:59-105).
A peer that vanishes without a close frame keeps its WebsocketConnectionActor child and its entry in WebsocketServerActor._clients (src/http/websocket/WebsocketServerActor.ts:45) forever — and the dead connection counts against the maxConnections cap.
Proposed behaviour
Add withHeartbeatIntervalMs / withIdleTimeoutMs to WebsocketRouteOptions + HOCON under actor-ts.http.websocket, resolved by resolveWebsocketPolicy. Send protocol-level pings from the connection actor; close 1001 after N missed pongs or after idle.
Acceptance criteria
- A socket whose peer is force-killed is reaped within the configured window on all three backends;
maxConnections accounting recovers.
Related: #570 (close-before-attach leak on Hono — different mechanism, same symptom family)
Problem
The WebSocket client has a heartbeat:
pingIntervalMs(src/http/websocket/WebsocketClientOptions.ts:46, driven atsrc/http/websocket/WebsocketClientActor.ts:178-180). The server side has no equivalent:ResolvedWebsocketPolicycovers only frame size, invalid messages, backpressure andmaxConnections(src/http/websocket/WebsocketPolicy.ts:19-31), andWebsocketRouteOptionsBuilderhas nowithHeartbeat*/withIdleTimeout*(src/http/websocket/WebsocketRouteOptions.ts:59-105).A peer that vanishes without a close frame keeps its
WebsocketConnectionActorchild and its entry inWebsocketServerActor._clients(src/http/websocket/WebsocketServerActor.ts:45) forever — and the dead connection counts against themaxConnectionscap.Proposed behaviour
Add
withHeartbeatIntervalMs/withIdleTimeoutMstoWebsocketRouteOptions+ HOCON underactor-ts.http.websocket, resolved byresolveWebsocketPolicy. Send protocol-level pings from the connection actor; close 1001 after N missed pongs or after idle.Acceptance criteria
maxConnectionsaccounting recovers.Related: #570 (close-before-attach leak on Hono — different mechanism, same symptom family)