Blazor Server结合SignalR长时间运行后客户端异常问题求助
Blazor Server长时间运行客户端故障排查方案
针对Blazor Server应用运行10小时以上出现页面切换失效、SignalR数据停止刷新的问题,可从以下方向排查解决:
一、优化SignalR连接与重连机制
- 配置SignalR的超时与保活参数,避免隐性断连:
builder.Services.AddServerSideBlazor() .AddHubOptions(options => { options.ClientTimeoutInterval = TimeSpan.FromMinutes(5); options.KeepAliveInterval = TimeSpan.FromMinutes(2); }) .AddCircuitOptions(options => { options.DisconnectedCircuitRetentionPeriod = TimeSpan.FromMinutes(10); options.MaxRetainedCircuits = 100; }); - 在客户端
_Host.cshtml中添加自动重连逻辑,当连接断开时自动刷新页面:window.addEventListener('blazor:disconnected', () => { setTimeout(() => { window.location.reload(); }, 5000); // 5秒后自动触发页面刷新 });
二、排查组件内存泄漏
- 所有订阅事件或SignalR数据流的组件,必须在
DisposeAsync中取消订阅,防止内存堆积:private IDisposable? _dataUpdateSubscription; protected override async Task OnInitializedAsync() { _dataUpdateSubscription = _realTimeHub.ReceiveDataUpdates.Subscribe(UpdateDisplayData); } public async ValueTask DisposeAsync() { _dataUpdateSubscription?.Dispose(); await base.DisposeAsync(); } - 使用浏览器开发者工具的Memory面板,定期抓取内存快照,对比长时间运行前后的内存占用,定位未释放的对象实例。
三、优化服务器端资源管理
- 检查服务器端是否存在长时间运行的同步任务,尽量将同步操作转为异步,避免阻塞Blazor电路线程。
- 合理配置电路回收策略,避免无效电路占用过多服务器资源,可通过
DisconnectedCircuitRetentionPeriod和MaxRetainedCircuits参数调整。
四、网络层面排查
- 确认服务器与客户端之间的防火墙、负载均衡器等网络设备,其连接超时设置大于SignalR的
KeepAliveInterval,防止中间设备主动断开长连接。 - 测试不同浏览器的表现,部分浏览器对长连接有更严格的限制,可针对性调整浏览器设置或提示用户更换兼容浏览器。
五、补充详细日志
- 在SignalR Hub中添加连接状态日志,便于追踪断连时机:
public override async Task OnConnectedAsync() { _logger.LogInformation($"Circuit {Context.ConnectionId} 已连接"); await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception? exception) { _logger.LogInformation($"Circuit {Context.ConnectionId} 断开连接,异常信息:{exception?.Message ?? "无"}"); await base.OnDisconnectedAsync(exception); } - 在客户端添加JavaScript日志,记录SignalR连接状态变化,定位问题发生时的客户端状态:
window.addEventListener('blazor:connected', () => console.log('Blazor连接已建立')); window.addEventListener('blazor:reconnecting', () => console.log('Blazor正在重连')); window.addEventListener('blazor:reconnected', () => console.log('Blazor重连成功'));
内容的提问来源于stack exchange,提问作者Roberto Marchesi
相关产品推荐
相关产品推荐

