Skip to main content

Reconnect & Retry

Two reconnect mechanisms exist, and they are complementary:

  • Automatic reconnect re-establishes the connection and re-runs negotiation + handshake. Pending invocations are failed.
  • Stateful reconnect reuses the same logical connection and replays buffered messages (see Stateful Reconnect).

Enabling automatic reconnect

connection = HubConnection().with_retry_policy(DefaultRetryPolicy())

or a custom policy:

from aiosignalr.client import HubConnection, RetryContext, RetryPolicy


class FastRetry(RetryPolicy):
def next_retry_delay(self, context: RetryContext) -> float | None:
return {0: 0.0, 1: 0.05, 2: 0.05}.get(context.previous_retry_count)


connection = HubConnection().with_retry_policy(FastRetry())

RetryPolicy contract

RetryPolicy.next_retry_delay(context: RetryContext) -> float | None

  • Returns the delay in seconds before the next attempt.
  • Returns None to stop retrying (the connection then goes DISCONNECTED and on_close fires).
  • RetryContext provides:
    • previous_retry_count — attempts so far.
    • elapsed_time — seconds since the reconnect cycle started.
    • retry_reason — the exception that caused the disconnect.

DefaultRetryPolicy

Mirrors ASP.NET Core: 0s, 2s, 10s, 30s, then stop.

Lifecycle during a reconnect

  1. The transport closes for an unexpected reason.
  2. If a retry policy is configured and the connection is not stopping, the client enters RECONNECTING and fires on_reconnecting.
  3. On each attempt it sleeps the policy delay, then reconnects (negotiate + transport + handshake).
  4. On success it fires on_reconnected and returns to CONNECTED.
  5. If the policy returns None (or the delay/connection raises exhaust the policy), the client fires on_close.

Pending invocations (invoke, stream) are failed with the close reason when the connection drops.

Server timeout

If no message arrives within HubConnectionOptions.server_timeout (default 30s), the client raises ServerTimeout and closes the connection — which then goes through the reconnect flow if a retry policy is configured.

connection = HubConnection(options=HubConnectionOptions(server_timeout=15.0))

Which one should I use?

  • Regular HTTP round-trips / request-response: automatic reconnect is enough.
  • Streaming, broadcasts, long-lived state: enable stateful reconnect so messages sent while the connection is down are not lost, and received duplicates are filtered.
  • You can combine both: use with_stateful_reconnect() and with_retry_policy(...). If the stateful transport reconnect fails, the client falls back to the regular reconnect flow.