跳到主要内容

重连与重试

存在两种重连机制,二者互补:

  • 自动重连重建连接并重新执行协商与握手。挂起的调用会失败。
  • 状态化重连复用同一条逻辑连接并重放缓冲消息 (见状态化重连)。

开启自动重连

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

或自定义策略:

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 契约

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

  • 返回下一次尝试前的等待秒数。
  • 返回 None 停止重试(连接随后进入 DISCONNECTED 并触发 on_close)。
  • RetryContext 提供:
    • previous_retry_count —— 已尝试次数。
    • elapsed_time —— 本轮重连开始以来的秒数。
    • retry_reason —— 导致断开的异常。

DefaultRetryPolicy

对齐 ASP.NET Core:0s2s10s30s,然后停止。

重连期间的生命周期

  1. 传输因意外原因关闭。
  2. 若配置了重试策略且连接不在停止中,客户端进入 RECONNECTING 并触发 on_reconnecting
  3. 每次尝试先按策略等待,再重连(协商 + 传输 + 握手)。
  4. 成功后触发 on_reconnected 并回到 CONNECTED
  5. 策略返回 None(或连续失败耗尽策略)时,触发 on_close

连接断开时,挂起的调用(invokestream)以断开原因失败。

服务端超时

HubConnectionOptions.server_timeout(默认 30s)内没有消息到达, 客户端抛 ServerTimeout 并关闭连接 —— 配置了重试策略的话随后进入重连流程。

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

该用哪个?

  • 普通 HTTP 往返 / 请求响应:自动重连就够了。
  • 流式、广播、长生命周期状态:开启状态化重连,连接断开期间发送的消息不丢, 收到的重复消息会被过滤。
  • 两者可以组合:同时用 with_stateful_reconnect()with_retry_policy(...)。 状态化传输重连失败时,客户端回落到普通重连流程。