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
| Protocol | Value | Transfer format | Notes |
|---|---|---|---|
| JSON | "json" | Text | Default. Human-readable, 0x1E-delimited |
| MessagePack | "messagepack" | Binary | Smaller 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_factoryis called before each HTTP/WebSocket request; a non-Noneresult is sent asAuthorization: Bearer <token>. It may be a coroutine.transportslimits which transports the client is allowed to use.skip_negotiation=Trueconnects 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
| Event | Signature | Fires when |
|---|---|---|
on_open | () -> None | Connected for the first time |
on_close | (exc) -> None | Connection fully closed (permanently) |
on_reconnecting | (exc) -> None | A reconnect cycle starts |
on_reconnected | () -> None | A reconnect succeeded |
Callbacks may be sync or async.
Timeouts and keep-alive
- Server timeout: if no message is received within
server_timeoutseconds, 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
Pingeverykeep_alive_intervalseconds 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.