Pulse/internal/websocket
rcourtman 58864f5ecc Accept any inbound websocket frame as proof of client liveness
The read deadline was refreshed only by protocol pong frames, so a client
whose ping/pong control frames were delayed more than 6 seconds or eaten
by a middlebox (Cloudflare edge, AV proxies) was killed every 60 seconds
even while its 30-second JSON heartbeats were arriving. Demo logs show
the signature clearly: sessions dying at exactly 60s/114s/168s, i.e.
zero, one, or two pongs before execution, while the user watched the
badge cycle through Reconnecting on an otherwise healthy connection.

Refresh the read deadline on every successful read, widen it to 90s so a
background tab throttled to one heartbeat per minute still survives, and
ping every 30s so pong-only clients tolerate two lost round trips.

Contract-Neutral: websocket keepalive hardening: read-deadline/ping cadence only, no payload or contract delta
2026-08-05 12:24:07 +01:00
..
concurrency_test.go Fix settings security tab navigation 2025-10-11 23:29:47 +00:00
hub.go Accept any inbound websocket frame as proof of client liveness 2026-08-05 12:24:07 +01:00
hub_alert_tenant_test.go feat: Pulse v6 release 2026-03-18 16:06:30 +00:00
hub_concurrency_test.go refactor: use strconv.Itoa instead of string(rune()) in test 2025-10-20 15:12:14 +00:00
hub_more2_test.go Require explicit websocket origin continuity 2026-04-22 04:46:13 +01:00
hub_more_test.go Bound state refresh and recovery ingest ownership 2026-07-23 22:24:52 +01:00
hub_multitenant_test.go Harden remaining CodeQL security boundaries 2026-07-09 19:46:40 +01:00
hub_observability_test.go feat: Pulse v6 release 2026-03-18 16:06:30 +00:00
hub_tenant_test.go Fix websocket state broadcast retention 2026-06-24 11:16:27 +01:00
hub_test.go Document websocket lifecycle synchronization 2026-07-26 22:02:22 +01:00