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

Blazor WebAssembly聊天应用SignalR的OnDisconnectedAsync方法未触发问题

解决方法

1. 适配非正常断开的超时逻辑

直接关闭浏览器属于非正常断开场景,客户端不会主动向服务端发送断开信号,SignalR服务端默认设置了30秒的DisconnectTimeout超时,超时后才会判定客户端离线并触发OnDisconnectedAsync方法。关闭浏览器后保持服务端运行30秒以上,即可观察到断点命中。
调试阶段可以临时缩短超时时间加快验证,在服务端Program.cs中修改配置:

builder.Services.AddSignalR(opt =>
{
    // 调试用超时时间,生产环境建议保留默认30秒
    opt.DisconnectTimeout = TimeSpan.FromSeconds(5);
});

2. 补充客户端主动断开逻辑

如果需要用户关闭页面/退出应用时立即触发离线回调,需要在Blazor WebAssembly客户端补充连接销毁逻辑,主动通知服务端断开:

// 客户端维护SignalR连接的组件中添加销毁逻辑
protected override async ValueTask DisposeAsync()
{
    if (HubConnection != null)
    {
        await HubConnection.StopAsync();
        await HubConnection.DisposeAsync();
    }
    await base.DisposeAsync();
}

3. 完善服务端方法的异常处理

当前实现缺少空判断和异常捕获,若Context.User为空会抛出异常导致方法提前终止,可能影响调试命中,建议调整实现:

public override async Task OnDisconnectedAsync(Exception? exception)
{
    var userId = _userManager.GetUserId(Context?.User);
    if (!string.IsNullOrEmpty(userId))
    {
        // 此处添加离线状态广播逻辑
    }
    await base.OnDisconnectedAsync(exception);
}

4. 开启Debug日志排查底层问题

如果上述操作后依然无法触发,可在服务端appsettings.json中开启SignalR调试日志,定位是否存在中间件拦截、认证失效等底层问题:

{
  "Logging": {
    "LogLevel": {
      "Microsoft.AspNetCore.SignalR": "Debug",
      "Microsoft.AspNetCore.Http.Connections": "Debug"
    }
  }
}

启动服务后复现断开场景,查看日志中是否存在断开相关的报错记录即可定位问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:54:02