我正在用Durandal编写单页应用程序,我正在计划使用SignalR来实现某些功能。首先,我有一个顶部栏,用于侦听服务器可能发送的通知。该站点开始连接到“TopBarNotificationHub”。
在我希望连接到另一个集线器的其中一个页面上,因为两个用户可能同时编辑此页面上的数据,并且我想通知是否有人更新了数据。没问题,这很好用。
但是,当我离开那个页面时,我只想断开与第二个集线器的连接,但我找不到办法来实现这个目标。如果我只是说hub.connection.stop();与eTopBarNotificationHub的连接也会停止(因为它已共享)。
有没有办法只留下一个hubproxy并让另一个存在?
由于这是一个SPA,“shell”永远不会重新加载,因此它不会再次连接到集线器...我可能会强制这个重新连接每次另一个页面断开与集线器,但可能有一个清洁解决方案......
提前致谢。
∥焦
答案 0 :(得分:7)
如果您在单个页面上使用多个集线器,但它们共享相同的连接,那么除了接收更新之外,它不会占用客户端上的更多资源。
因此,要“连接和断开集线器”,您需要稍微重新架构。如果您在服务器端使用组而不是客户端,则可以通过调用(例如)Hub1.Register
方法并在该方法中将客户端粘贴到相关组中来“注册”Hub。要“取消注册”,您可以调用(例如)Hub1.DeRegister
并从该方法中的组中删除客户端的ConnectionId
。然后,当您将更新推送到客户端时,您可以使用该组而不是Clients.All
。
(C#假设您使用服务器语言,而未在标记中指定)
Groups.Add(Context.ConnectionId, groupNameForHub);
Groups.Remove(Context.ConnectionId, id.ToString());
Clients.Group(groupNameForHub).clientMethodName(param1, param2);
但是,为了让它变得混乱,请注意Hub1中名为“myGroup”的组与Hub2中名为“myGroup”的组分开。
这是推荐的确切方法in the documents(如果在以后的版本中移动/更改,则复制在此处):
多个中心
您可以在应用程序中定义多个Hub类。执行此操作时,将共享连接,但组是分开的:
•所有客户端将使用相同的URL与您的服务建立SignalR连接(“/ signalr”或您指定的自定义URL),并且该连接用于该服务定义的所有集线器。
与在单个类中定义所有Hub功能相比,多个Hub没有性能差异。
•所有集线器都获得相同的HTTP请求信息。
由于所有集线器共享相同的连接,因此服务器获取的唯一HTTP请求信息是建立SignalR连接的原始HTTP请求中的内容。如果使用连接请求通过指定查询字符串将信息从客户端传递到服务器,则无法向不同的集线器提供不同的查询字符串。所有中心都将收到相同的信息。
•生成的JavaScript代理文件将包含一个文件中所有集线器的代理。
有关JavaScript代理的信息,请参阅SignalR Hubs API Guide - JavaScript Client - The generated proxy and what it does for you。
•在集线器中定义组。
在SignalR中,您可以定义命名组以广播到已连接客户端的子集。每个Hub都单独维护组。例如,名为“Administrators”的组将包含ContosoChatHub类的一组客户端,同一组名称将引用StockTickerHub类的另一组客户端。