.NET Core 6 Blazor SignalR连接堆积超限问题求助
SignalR连接堆积问题分析与解决
核心问题
你遇到的连接堆积,本质是组件销毁时未主动断开SignalR连接,加上自动重连机制的影响,导致服务器端无法及时清理无效连接,最终触发连接上限。
具体来说:
- 页面刷新会销毁当前所有组件实例,但你只在
OnInitializedAsync中创建连接,没有在组件销毁时执行断开逻辑,旧连接会在服务器端保持存活状态(直到超时)。 WithAutomaticReconnect()会让旧客户端实例(即使页面已刷新)尝试重连,进一步加剧连接堆积。
解决方案
1. 组件销毁时主动断开连接
让组件实现IAsyncDisposable接口,在异步销毁方法中主动停止并释放Hub连接:
public async ValueTask DisposeAsync() { if (hubConnection != null) { // 先停止连接 await hubConnection.StopAsync(); // 释放连接资源 await hubConnection.DisposeAsync(); } }
2. 复用Hub连接(推荐)
每个拍卖组件单独创建连接会大幅增加服务器连接数,更优的方式是全局复用一个Hub连接实例:
步骤1:注册单例Hub连接
在Program.cs中注册全局单例的HubConnection:
builder.Services.AddSingleton<HubConnection>(sp => { var navigationManager = sp.GetRequiredService<NavigationManager>(); var container = ...; // 替换为你的Cookie容器获取逻辑 return new HubConnectionBuilder() .WithUrl(navigationManager.ToAbsoluteUri("auctionhub"), options => { options.Cookies = container; }) .WithAutomaticReconnect() .Build(); });
步骤2:组件中注入并使用共享连接
[Inject] private HubConnection HubConnection { get; set; } protected override async Task OnInitializedAsync() { // 仅在连接断开时启动 if (HubConnection.State == HubConnectionState.Disconnected) { HubConnection.ServerTimeout = TimeSpan.FromSeconds(30); HubConnection.HandshakeTimeout = TimeSpan.FromSeconds(15); HubConnection.KeepAliveInterval = TimeSpan.FromSeconds(15); await HubConnection.StartAsync(); } // 注册当前组件的更新回调 HubConnection.On("UpdateBids", () => GetAuction()); } // 销毁时移除当前组件的回调 public async ValueTask DisposeAsync() { HubConnection.Remove("UpdateBids"); }
这种方式下,不管有多少个拍卖组件,都共用一个SignalR连接,从根源上避免连接堆积问题。
3. 补充服务器端配置检查
确保服务器端SignalR配置了合理的连接超时清理:
builder.Services.AddSignalR(options => { // 设置服务器端连接超时,比客户端超时短一点 options.ClientTimeoutInterval = TimeSpan.FromSeconds(25); options.KeepAliveInterval = TimeSpan.FromSeconds(10); });
内容的提问来源于stack exchange,提问作者GeeksGoneBad
相关产品推荐
相关产品推荐

