【问题标题】:Calling all SignalR clients in a group from server从服务器调用组中的所有 SignalR 客户端
【发布时间】:2015-03-20 11:28:11
【问题描述】:

我需要从我的服务器后端调用组中的所有 SignalR 客户端。

我需要 Clients.OthersInGroup('MyGroupName').MyFunction 的等价物,但需要通过 IHubContext 对象(或从 Hub 实例外部)。这有可能吗?

我的用例:我有一个提供商托管的 SharePoint 应用程序。 SignalR 用于实时更新其他客户端的更改(使用 SignalR JavaScript 客户端)。由于该应用程序支持多租户,因此连接到服务器的客户端可以来自不同的 SharePoints 租户。通信应始终仅在同一租户的客户端之间进行。因此,如果客户端连接,则会将其添加到他的 SharePoint 租户的 SignalR 组中。 现在有一些操作,比如显示一个文档,如果它不存在就创建它,发生在服务器上。在这种情况下,客户端调用后端的 URL,然后返回文档。如果它是新创建的,则应将其传达回受影响租户的客户端。

【问题讨论】:

  • 您能否修改问题并添加一些有关您的用例以及您想要实现的目标的更多信息? OthersInGroup 之类的功能通常只有在 Hub 内部使用时才有意义。
  • 如果我理解正确,您希望向租户中的所有人显示此通知,创建文档的用户除外。对吗?
  • 是的,这正是我的情况。
  • 例外,在这种特殊情况下甚至对租户中的每个人(包括创建请求的客户)都是如此。我使用 SharePoint SiteCollection URL 作为组标识符,因此每个人都从同一个 SharePoint URL(=相同的 SignalR 组)连接。服务器代码知道创建文档的 SharePoint 网站集 url。

标签: signalr


【解决方案1】:

注意:此答案经过编辑以反映相关问题中提供的其他信息。

这个问题可以通过多种方式解决:

方法一:

向属于租户的所有客户转发通知(我假设您使用租户标识符作为组名)。在通知消息中包含文档作者的标识。然后在处理客户端通知的代码中决定用户是否是文档的作者。如果他(她)是,请不要显示通知。

这样,您无需在应用程序的服务器端进行任何特殊过滤,您只需使用标准 API。

方法二:

您必须在 SignaR 连接和用户之间创建某种映射。如果您的应用程序在单个服务器上运行,您可以将此信息存储在一些静态地图中。如果您的提供商托管的应用程序在农场中运行,您必须使用 Redis 之类的东西。用户和连接之间的映射可以在集线器的OnConnected(将连接ID​​添加到地图)和OnDisconnected(从地图中删除连接ID)方法中完成。

然后当你要发送通知时,使用IHubContext.ClientsGroup 方法,从地图中获取属于文档作者的连接列表,并将它们作为应该忽略的连接传递。

类似这样的:

string[] connectionIdsBelongingToAuthor = // get from mapping, these will be ignored
string groupName = // get group which should be notified

hubContext.Clients.Group(groupName, connectionIdsBelongingToAuthor).NotificationMethod(...)

我会采用方法 1 并决定是否应在客户端显示通知。

【讨论】:

  • 很遗憾,我不知道要排除的 ID。我有未知数量的组,服务器只知道他需要呼叫的组。为了调用AllExcept,我需要首先确定所有其他组的所有连接。到目前为止,我还没有找到检索这些信息的方法。
  • 感谢更新的答案。但我认为这不适合我的用例。方法一:我应该如何识别属于租户的所有客户?这正是我无法工作的地方。同一租户的客户端在同一组中。但我无法从集线器外部访问这些信息。方法 2 可能有效,但最终我需要或多或少地重新实现信号器集线器的组逻辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多