Blazor Server部署到域名环境后SignalR WebSocket连接异常
问题详情
基于.NET 6开发的Blazor Server应用,使用SignalR实现WebSocket通信,本地运行正常,但部署到域名环境后出现连接超时错误,错误信息如下:
Category: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost EventId: 111
SpanId: 035e261646274bda TraceId: 409cb921befed7fb1fd2e9aebe4d3922 ParentId: 0000000000000000
RequestId: 800023fd-0001-e800-b63f-84710c7967bb RequestPath: /_blazor
TransportConnectionId: 5Zoh_eXhB5h8rS8JGG4rhw
Unhandled exception in circuit 'KV5FZtq0dX0PIWMTtQo5Jo-8_hp5lD6O_gm9C5pCWNs'.
Exception: System.Net.Http.HttpRequestException: 连接尝试失败,因为连接方在一段时间后没有正确响应,或者已建立的连接失败,因为连接的主机未能响应。(demo.domain.com:443)
---> System.Net.Sockets.SocketException (10060): 连接尝试失败,因为连接方在一段时间后没有正确响应,或者已建立的连接失败,因为连接的主机未能响应。
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
相关代码:
Program.cs 配置
builder.Services.AddCors(); builder.Services.AddSignalR(); builder.Services.AddResponseCompression(opts => { opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "application/octet-stream" }); }); ... app.UseResponseCompression(); app.MapHub<ExampleHub>("/ehub");
客户端连接代码
hubConnection = new HubConnectionBuilder().WithUrl(NavigationManager.ToAbsoluteUri("/ehub"), options => { options.Transports = HttpTransportType.WebSockets; }).WithAutomaticReconnect().Build(); await hubConnection.StartAsync();
解决步骤
1. 完善CORS配置
当前代码仅调用AddCors()但未配置具体规则,SignalR需要允许凭证和指定允许的源。修改Program.cs:
// 在app.UseRouting()之后、app.UseAuthorization()之前添加 app.UseCors(policy => { policy.WithOrigins("https://demo.domain.com") // 替换为你的实际域名 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); // 必须开启,SignalR需要携带凭证 }); // 确保UseResponseCompression和MapHub在UseCors之后 app.UseResponseCompression(); app.MapHub<ExampleHub>("/ehub");
2. 确保反向代理/服务器支持WebSocket
如果使用IIS、Nginx等反向代理,必须开启WebSocket支持:
- IIS:在服务器管理器中安装「WebSocket协议」功能(路径:Web服务器 -> 应用程序开发 -> WebSocket协议),并确保站点绑定的SSL证书有效。
- Nginx:在配置文件中添加WebSocket转发规则:
location /ehub { proxy_pass http://你的后端服务地址; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; }
- Apache:启用
mod_proxy_wstunnel模块,添加配置:
ProxyPass /ehub ws://你的后端服务地址/ehub ProxyPassReverse /ehub ws://你的后端服务地址/ehub
3. 调整客户端连接配置
- 调试时输出
hubConnection.Uri,确认生成的地址是https://demo.domain.com/ehub,避免NavigationManager生成错误的地址。 - 若反向代理已处理协商逻辑,可添加
SkipNegotiation配置:
options.SkipNegotiation = true; options.Transports = HttpTransportType.WebSockets;
4. 排查网络防火墙/安全组
- 确认域名对应的服务器443端口(HTTPS)已在云服务商安全组(如阿里云、腾讯云)和本地防火墙(Windows防火墙、iptables)中放行。
- 检查是否有CDN或WAF拦截了WebSocket连接,部分CDN需要手动开启WebSocket支持。
5. 验证SSL证书有效性
确保使用的SSL证书是受信任的(如Let's Encrypt免费证书),避免因证书不信任导致连接失败。自签名证书需在客户端信任,但生产环境不建议使用。
内容的提问来源于stack exchange,提问作者Serhat Morkoç

