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

SignalR客户端升级后Windows Server 2012 R2上HTTP/2握手失败问题排查

问题描述

我有基于.NET 6的SignalR服务器(Hub)和C#客户端,服务器使用Let's Encrypt证书。将SignalR客户端从6.0.10升级至7.0.12后,一台Windows Server 2012 R2客户端电脑在调用StartAsync方法时抛出异常:

An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake

客户端代码如下:

_hubConnection = new HubConnectionBuilder().WithUrl($"{_setting.HubUrl}/hubs/tariff")
  .AddJsonProtocol(options => options.PayloadSerializerOptions.PropertyNamingPolicy = null).Build();
await _hubConnection.StartAsync(); // <-- 抛出HttpRequestException异常

本地客户端测试无异常,需解决该问题,同时询问是否有强制禁用HTTP/2的方案。

堆栈跟踪关键信息:

System.Net.Http.HttpRequestException: An HTTP/2 connection could not be established because the server did not complete the HTTP/2 handshake.
   at System.Net.Http.HttpConnectionPool.ReturnHttp2Connection(Http2Connection connection, Boolean isNewConnection)
   ...
   at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
解决方案

1. 强制禁用HTTP/2(针对Windows Server 2012 R2的核心解决方法)

Windows Server 2012 R2原生对HTTP/2支持有限,升级后的SignalR 7.x客户端默认优先尝试HTTP/2连接,导致握手失败。可通过配置HttpClient强制使用HTTP/1.1:

修改客户端代码如下:

_hubConnection = new HubConnectionBuilder()
    .WithUrl($"{_setting.HubUrl}/hubs/tariff", options =>
    {
        options.HttpMessageHandlerFactory = _ => new HttpClientHandler
        {
            // 强制使用HTTP/1.1
            DefaultRequestVersion = HttpVersion.Version11,
            MaxResponseContentBufferSize = 1024 * 1024 * 10, // 可根据需求调整缓存大小
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
        };
    })
    .AddJsonProtocol(options => options.PayloadSerializerOptions.PropertyNamingPolicy = null)
    .Build();

await _hubConnection.StartAsync();

注:如果不需要跳过证书验证,不要添加ServerCertificateCustomValidationCallback相关代码,需确保Windows Server 2012 R2信任Let's Encrypt的根证书。

2. 更新Windows Server 2012 R2的根证书

Let's Encrypt的ISRG Root X1根证书在Windows Server 2012 R2中默认可能未更新,会导致SSL握手异常间接引发HTTP/2握手失败。手动更新步骤:

  • 获取Let's Encrypt官方最新的ISRG Root X1根证书
  • 运行certmgr.msc,将证书导入至「受信任的根证书颁发机构」

3. 服务器端可选配置(限制HTTP版本)

若希望服务器端统一限制HTTP版本,可在SignalR服务器的Program.cs中配置Kestrel强制使用HTTP/1.1(会影响所有客户端):

builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(5001, listenOptions =>
    {
        listenOptions.UseHttps("your-certificate.pfx", "cert-password");
        listenOptions.Protocols = HttpProtocols.Http1;
    });
});

4. 其他排查点

  • 确认Windows Server 2012 R2已安装.NET 6或更高版本的运行时(SignalR 7.x客户端依赖该环境)
  • 检查服务器端SignalR Hub的跨域、路由配置是否有变更
  • 使用命令行工具测试服务器的HTTP/2支持:curl -v --http2 https://your-server-url/hubs/tariff/negotiate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:10:55