You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SignalR自动重连时服务端无法区分首次连接与重连请求

解决方案

方案一:客户端重连时添加自定义请求头

在客户端通过重连事件给重连请求添加专属标识头,服务端中间件通过该头识别重连请求:

客户端代码修改

this.hubConn = new HubConnectionBuilder()
  .withUrl("https://server/hubEndPoint", {
      skipNegotiation: true,
      transport: HttpTransportType.WebSockets
  })
  .withAutomaticReconnect()
  .build();

// 监听重连开始事件,添加重连标识头
this.hubConn.onReconnecting((error) => {
  this.hubConn.options.headers['X-SignalR-Reconnect'] = 'true';
});

// 重连成功后重置请求头(可选)
this.hubConn.onReconnected((connectionId) => {
  delete this.hubConn.options.headers['X-SignalR-Reconnect'];
});

服务端中间件处理

在中间件中检查请求头X-SignalR-Reconnect,判断是否为重连请求:

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
    if (context.Request.Path.StartsWithSegments("/hubEndPoint") 
        && context.Request.Method == HttpMethod.Get.Method)
    {
        bool isReconnect = context.Request.Headers.TryGetValue("X-SignalR-Reconnect", out var reconnectHeader) 
                           && reconnectHeader == "true";
        
        if (isReconnect)
        {
            // 执行重连请求的处理逻辑
        }
        else
        {
            // 执行首次连接请求的处理逻辑
        }
    }

    await next(context);
}

方案二:通过Connection-Id识别重连

SignalR自动重连时会尝试复用之前的Connection-Id,服务端可通过记录历史Connection-Id来判断是否为重连请求:

服务端逻辑

// 维护历史Connection-Id集合,需注意定期清理过期Id避免内存泄漏
private readonly HashSet<string> _historicalConnectionIds = new HashSet<string>();

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
    if (context.Request.Path.StartsWithSegments("/hubEndPoint") 
        && context.Request.Method == HttpMethod.Get.Method)
    {
        if (context.Request.Headers.TryGetValue("Connection-Id", out var connectionId))
        {
            bool isReconnect = _historicalConnectionIds.Contains(connectionId);
            
            if (isReconnect)
            {
                // 执行重连请求的处理逻辑
            }
            else
            {
                // 首次连接,记录Connection-Id
                _historicalConnectionIds.Add(connectionId);
                // 执行首次连接请求的处理逻辑
            }
        }
    }

    await next(context);
}

注意:需在连接断开事件中移除对应Connection-Id,避免集合无限膨胀。


内容的提问来源于stack exchange,提问作者Dimitri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:35:18