首页 > 解决方案 > SignalR 可以在客户端断开连接时对消息进行排队,并在客户端连接回来时将它们重新发送给客户端吗?

问题描述

我们目前使用 SignalR 从我们的 UI 客户端上的后端接收实时消息。UI 客户端在联机并连接到 SignalR 时接收消息,并在断开连接时错过消息(例如:用户关闭页面并且 SignalR 断开客户端连接)。但是,现在我们需要向用户显示所有消息,包括在 UI 客户端离线时由 SignalR 发送的消息。SignalR 可以支持这种情况吗?该要求类似于 UI 客户端消息的持久队列,但我们使用 SignalR 向所有客户端广播消息。

标签: signalrsignalr-hubsignalr.clientasp.net-core-signalrsignalr-backplane

解决方案


SignalR 不支持这种情况,需要自己做。您需要存储消息并实现一个集线器方法,将待处理的数据发送到连接的客户端。所以你需要做的是:

  • 使用选项将数据保存在一些易失性存储中readby,这样您就可以看到已经发送到客户端的数据并将其删除。
  • 将数据发送到客户端的集线器方法,客户端响应接收到的数据。
  • 集线器方法,将在客户端断开连接时发送集线器未发送的所有数据。

代码示例,在客户端,连接并获取以前的数据:

/**
* Connect signalR and get previous data
*/
private async connectSignalR() {
  await this.hubMessageConnection.start()
    .then(() => {
      // Register application
      this.GetDataForThisClientAsync();
    }).catch(() => {
      this.onError.emit(WidgetStateEnum.connectError);
    });
}

和集线器方法来获取数据:

公共异步任务<OperationResult> GetNotificationsAsync(组组)
{
    IList<MyData> 数据 = 等待 this.DataManager.GetDataForThisClientAsync(groups).ConfigureAwait(false);

    如果(数据。计数!= 0)
    {
        // 发送通知

        foreach(数据中的 MyData 数据)
        {
            等待 this.BroadcastDataToCallerAsync(data).ConfigureAwait(false);
        }
    }

    返回 OperationResult.Success();
}

推荐阅读