Skip to content

[Codex] Add websocket heartbeat and idle reconnect#10

Closed
dansimau wants to merge 1 commit into
mainfrom
codex/fix-websocket-connection-issue
Closed

[Codex] Add websocket heartbeat and idle reconnect#10
dansimau wants to merge 1 commit into
mainfrom
codex/fix-websocket-connection-issue

Conversation

@dansimau

Copy link
Copy Markdown
Owner

Motivation

  • Connections to Home Assistant could appear live but stop receiving events, causing automations to stall without triggering a reconnect.
  • Introduce both protocol-level health checks (ping/pong/read-deadline) and an application-level inactivity detector to detect and recover from silent websockets.

Description

  • Added new configuration fields WebSocketPingInterval, WebSocketPongTimeout, and WebSocketIdleTimeout to Config and plumbed them into the hassws ClientConfig so behavior is configurable at runtime.
  • Implemented heartbeat logic in hassws.Client: periodic ping frames, a PongHandler and read-deadline management, plus a lastDataReceived timestamp updated on every frame.
  • Added application-level idle detection that closes the socket when no frames are received within the configured inactivity timeout, which allows the existing reconnect loop to reconnect and resubscribe.
  • Serialized websocket writes via a writeMu mutex and added safe shutdown handling, and added the TestReconnectsAfterWebSocketIdleTimeout regression test to verify idle-induced reconnection and resubscription.

Testing

  • Ran go test ./... and all tests completed successfully.
  • The new TestReconnectsAfterWebSocketIdleTimeout test was added and included in the test run and passed.

Codex Task

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52fa2d0b1c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hassws/client.go

// Start listening for messages and monitoring connection health.
go c.listen()
go c.heartbeat()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Cancel per-connection heartbeat goroutines

When a disconnect is followed by a reconnect before the old heartbeat ticker wakes up, the heartbeat started for the previous socket does not exit because it only checks the client-wide stateConnected flag; after Connect sets that flag for the new socket, the old goroutine continues and operates on the shared c.conn. Each fast reconnect can therefore leave another ticker sending pings and running inactivity checks against the current connection, which can accumulate duplicate heartbeats and goroutines during network flapping. Tie the heartbeat to the specific connection or cancel it when that connection's listener exits.

Useful? React with 👍 / 👎.

Comment thread hassws/client.go
const (
defaultPingInterval = 30 * time.Second
defaultPongTimeout = 60 * time.Second
defaultInactivityTimeout = 10 * time.Minute

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't enable application-idle reconnects by default

With this default, any installation that has no subscribed Home Assistant event or command result for 10 minutes will be disconnected even though the websocket heartbeat is healthy, because markDataReceived only runs for data messages while pongs only extend the read deadline. In normal low-traffic homes this creates periodic reconnect windows and can drop events that happen during resubscription unless users discover and set a negative idle timeout, so the application-idle detector should be opt-in or count healthy heartbeat traffic separately from a truly stalled socket.

Useful? React with 👍 / 👎.

@dansimau dansimau changed the title Add websocket heartbeat and idle reconnect [Codex] Add websocket heartbeat and idle reconnect Jul 10, 2026
@dansimau dansimau closed this Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant