You need to enable JavaScript to run this app. ASP.NET Core 3.1 SignalR偶发无法向React应用返回数据如何解决
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 3.1 SignalR偶发无法向React应用返回数据如何解决

核心问题修复方案


1. 前端事件注册时序错误(主要诱因)

你当前的代码是先启动SignalR连接,再注册ShowMainLobby事件监听。当连接建立速度较快时,服务端OnConnectedAsync会在事件注册完成前就推送消息,导致前端漏收,多次操作后稳定复现加载卡住的问题。
修复后的React核心逻辑:

useEffect(() => {
  if (conn) {
    // 先注册事件,再启动连接
    conn.on("ShowMainLobby", (tournaments) => {
      setTournaments(tournaments);
      console.log(tournaments);
      setScreen("ShowMainLobby");
    });

    conn.start()
      .then((result) => {
        console.log("Connected");
      })
      .catch((ex) => console.log("connection Failed: ", ex));
  }

  // 组件卸载时清理连接和事件,避免内存泄漏
  return () => {
    if (conn) {
      conn.off("ShowMainLobby");
      conn.stop();
    }
  }
}, [conn]);

2. 服务端增加异常捕获与异步优化

服务端OnConnectedAsync未做异常捕获,一旦_tournamentsStore查询、AutoMapper映射、序列化任意环节出错,会直接中断推送,前端无任何反馈:

public override async Task OnConnectedAsync()
{
    try
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "Not playing");

        // 建议把GetAvailableTournaments改成异步方法,避免阻塞Hub线程
        var availableTournaments = _tournamentsStore.GetAvailableTournaments();
        var availableTournamentsDto = _mapper.Map<List<TournamentDto>>(availableTournaments);

        await Clients.Caller.ShowMainLobby(availableTournamentsDto);
        await base.OnConnectedAsync();
    }
    catch (Exception ex)
    {
        // 这里打日志排查具体错误,比如DTO序列化循环引用、存储查询超时等
        _logger.LogError(ex, "推送锦标赛列表失败,连接ID:{ConnectionId}", Context.ConnectionId);
        throw;
    }
}

3. 可选补充配置

如果服务端日志提示序列化错误,需要在Program.cs/Startup.cs中配置SignalR的System.Text.Json序列化规则,忽略循环引用:

services.AddSignalR()
    .AddJsonProtocol(options => {
        options.PayloadSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
    });

内容的提问来源于stack exchange,提问作者Hrvoje Brešić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 06:06:03