【问题标题】:SignalR issue with multiple tab多个选项卡的 SignalR 问题
【发布时间】:2019-09-10 22:08:03
【问题描述】:

我编写了一个使用 SignalR 的应用程序。我有搜索按钮来根据搜索条件获取数据。 (例如,如果您输入客户名称并单击搜索,则与客户名称相关的所有数据都将填充到屏幕上的网格中)

在我只打开一个浏览器的情况下,一切都很完美。但是,如果我打开同一浏览器的第二个实例,并且当我在新的浏览器选项卡上使用 TransactionDate 进行搜索时,它会复制第一个实例中的内容,即使它只适用于第二个实例。

我是 SignalR 的新手,我非常愿意提供任何帮助或指导。

Angular SignalRService 开始与 api 的连接

  this.hubConnection = new signalR.HubConnectionBuilder()
    .withUrl(this.paymentDraftHubUrl)
    .build();

  this.hubConnection
    .start()
    .then(() => this.hubConnectionStatus = 'Connection started')
    .catch(err => (this.hubConnectionStatus = 'Error while starting connection: ' + err));
}

C# 中的 Hub 类

public class PaymentDraftServiceHub : Hub, IPaymentDraftHub
{}

API 控制器
使用计时器不断调用存储库以获取新数据,

[HttpGet]
[Route("GetCsrTranactions")]
public IActionResult GetCsrTranactions([FromQuery] TransactionExceptionDataRequest queryParams)
{
    TimeManager.Dispose();
    var timerManager = new TimeManager(async () =>
    await _paymentDraftHub.Clients.All.SendAsync(SignalRConstants.TransferPaymentDraftServiceData, await _paymentTransactionRepository.GetCsrTranactionsAsync(queryParams)));
    var response = new ResponseMessage { Message = "Accepted", Code = "201" };
    return Ok(response);
}

我是 SignalR 的新手,非常希望得到任何帮助或指导。

【问题讨论】:

    标签: angular signalr asp.net-core-2.0 signalr-hub


    【解决方案1】:
    您在控制器中使用的

    Clients.All 方法将向所有当前连接的客户端发送消息。

    要仅将消息发送给呼叫者,您可以改用 Clients.Caller。 SignalR 在选择特定客户端时提供了更大的灵活性,您可以在 SignalR Documentation page 中阅读更多相关信息。

    【讨论】:

    • 正如您所建议的,我从客户端获得了 connectionId,并且我仅使用传递的 connectionId 向特定客户端发送响应。但是当我打开新浏览器并从该客户端发送请求时,先前的连接被处理。这意味着只有一个具有特定 connectionId 的连接仍然有效。有没有办法通过所有客户端保持连接? _paymentDraftHub.Clients.Clients.Client(queryParams.ConnectionId).SendAsync(SignalRConstants.TransferPaymentDraftServiceData, await _paymentTransactionRepository.GetCsrTranactionsAsync(queryParams)));
    • 您必须创建用户和连接的映射,如果您希望用户在浏览器会话中使用相同的连接,请查看此链接。 docs.microsoft.com/en-us/aspnet/signalr/overview/…
    【解决方案2】:

    我已经了解@krish 在他的回答中发布的文档,并准备了我的解决方案来处理不同的连接并向特定的 connectionId 发送响应。我还要求通过连接获得不同的参数,因此我还必须将参数保存到字典中。

    中心代码

    public string GetCsrTransactions(TransactionExceptionDataRequest queryParams)
    {
       if (Context.Items.TryGetValue(Context.ConnectionId, out _))
       {
         Context.Items.Remove(Context.ConnectionId);
         Context.Items.Add(Context.ConnectionId, queryParams);
       }
       else
       {
         Context.Items.Add(Context.ConnectionId, queryParams);
        }
    
        foreach (var item in Context.Items)
        {
          var isFounded = _disconnectedConnection.TryGetValue((string)item.Key, out _);
          if (!isFounded)
             _disconnectedConnection.Add((string)item.Key, queryParams);
          else
            {
              _disconnectedConnection.Remove((string)item.Key);
              _disconnectedConnection.Add((string)item.Key, queryParams);
             }
        }
    
        DataManager.Dispose();
        new DataManager(async () =>
        {
          var list = new Dictionary<string, TransactionExceptionDataRequest>(_disconnectedConnection);
          foreach (var item in list)
           {
            await _paymentDraftHub.Clients.Client(item.Key)
                                .SendAsync(SignalRConstants.TransferPaymentDraftServiceData,
    
            _paymentTransactionRepository.GetCsrTranactionsAsync(item.Value));
             }
            });
          return Context.ConnectionId;
      }
    
    public override async Task OnConnectedAsync()
    {
       await base.OnConnectedAsync();
    }
    
    public override async Task OnDisconnectedAsync(Exception exception)
    {
       Context.Items.Remove(Context.ConnectionId);
       await base.OnDisconnectedAsync(exception);
    }
    

    我希望这会对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多