从服务器调用组中的所有 SignalR 客户端

Calling all SignalR clients in a group from server

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

我需要 Clients.OthersInGroup('MyGroupName').MyFunction 的等价物,但需要通过 IHubContext 对象(或来自集线器实例外部的其他对象)。这有可能吗?

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

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

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

方法一:

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

这样,您不必在应用程序的服务器端进行任何特殊过滤,您可以只使用标准 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 并决定是否应在客户端中显示通知。