Skip to main content

HubConnection

HubConnection is the main client entry point. It manages the connection state machine, the negotiate → transport-select → connect → handshake flow, keep-alive pings, server-timeout detection and automatic reconnect.

Creating a connection

from aiosignalr.client import HubConnection

connection = HubConnection()

Options and protocol can be configured at construction time:

from aiosignalr.client import HubConnection, HubConnectionOptions

connection = HubConnection(
protocol="json", # or "messagepack", or a protocol instance
options=HubConnectionOptions(
handshake_timeout=15.0,
server_timeout=30.0,
keep_alive_interval=15.0,
),
)

Protocols

ProtocolValueTransfer formatNotes
JSON"json"TextDefault. Human-readable, 0x1E-delimited
MessagePack"messagepack"BinarySmaller and faster for high-volume traffic

You can also pass an IHubProtocol instance (e.g. a custom one).

Starting the connection

await connection.start(
"http://127.0.0.1:8080/hub",
access_token_factory=lambda: "my-token",
headers={"X-Custom": "value"},
transports={"WebSockets", "LongPolling"},
)
  • access_token_factory is called before each HTTP/WebSocket request; a non-None result is sent as Authorization: Bearer <token>. It may be a coroutine.
  • transports limits which transports the client is allowed to use.
  • skip_negotiation=True connects straight to a WebSocket URL without the negotiate step (requires the WebSockets transport).

start() raises if the connection is not in the DISCONNECTED state.

Stopping the connection

await connection.stop()

stop() sends a graceful Close message, stops the transports and timers, fails any pending invocations with ConnectionClosed("Connection stopped."), and fires on_close.

Connection state

from aiosignalr.enums import ConnectionState

connection.state # ConnectionState.DISCONNECTED / CONNECTING / CONNECTED / RECONNECTING

Connection events

Connection-level callbacks are plain assignable attributes:

connection.on_open = lambda: print("connected")
connection.on_close = lambda exc: print("closed:", exc)

async def on_reconnecting(exc):
print("reconnecting after", exc)

async def on_reconnected():
print("back online")

connection.on_reconnecting = on_reconnecting
connection.on_reconnected = on_reconnected
EventSignatureFires when
on_open() -> NoneConnected for the first time
on_close(exc) -> NoneConnection fully closed (permanently)
on_reconnecting(exc) -> NoneA reconnect cycle starts
on_reconnected() -> NoneA reconnect succeeded

Callbacks may be sync or async.

Timeouts and keep-alive

  • Server timeout: if no message is received within server_timeout seconds, the client assumes the connection is dead and closes it. This is required for transports that do not signal EOF on their own.
  • Keep-alive: the client sends a Ping every keep_alive_interval seconds so the server knows the client is still alive (and starts its own timeout).
  • The client only starts pinging once the hub handshake is complete, matching the reference implementation.

Enabling stateful reconnect

connection = HubConnection().with_stateful_reconnect()

See Stateful Reconnect for the full story. When the server advertises useStatefulReconnect, the client buffers unacknowledged outbound messages and replays them across transport drops.

Next steps