SignalR:如何在页面重新加载时停止创建新连接

时间:2013-11-27 04:21:32

标签: c# asp.net-mvc-4 signalr signalr-hub

您好我正在开发一个聊天应用程序以及我的应用程序中的其他一些页面。一旦我登录我正在维护用户的会话。我的主要目的是当用户连接到服务器时,用户应该收到通知。

我面临的问题是每当我导航到我的应用程序中的其他页面时,连接都会丢失。如何停止此行为并继续连接,直到用户注销。

我在ASP.NET MVC4项目中使用SignalR 2.0,任何帮助??

1 个答案:

答案 0 :(得分:5)

每个连接仅在用户在给定页面上花费的时间内具有生命周期。当他们导航到另一个页面时,会建立新的连接。此外,如果用户打开了多个选项卡或浏览器窗口,则它们将具有多个连接ID。我认为您不想尝试将连接ID​​保持在其预期的生命周期之外。

在我处理的类似场景中,我们存储connectionIds OnConnect并将其删除OnDisconnect。当需要将消息发送给给定用户时,我们将其发送到所有connectionIds。这可确保将消息传递到所有选项卡/窗口。

编辑1 以下内容是对@ Saurabh评论的回应:

考虑Hub的范围,以及其他类和客户端的范围。 Hub用于促进浏览器和服务器之间的通信。虽然可以在集线器中做很多工作,但我认为最好将大部分范围从通信范围转移到其他地方。

客户端知道它只是重新加载了一个页面,所以它是决定这是一个重新连接事件的好选择。

_chatHub.server.reJoinRooms();

然后,Hub可以通过UserId查询用户的房间,而不是ConnectionId。

public Task ReJoinRooms()
{
// get the user's rooms from your repository
// optionally get the user's connectionIds from your repository
// Clients.Caller.onJoinRooms(rooms);
// or Clients.Clients(_connectionIds).onJoinRooms(rooms);
}

然后客户可以决定是否采取行动:

$chatModule.client.onJoinRooms = function (rooms) {
   for (var i in rooms) {
           var _room = rooms[i];
           // if I'm not already in this room, add it to my rooms
           console.log('joining room', _room)
       }
}

你可以通过许多不同的方式进行修饰。客户端可以拥有记住房间的范围,而不是服务器端存储库。

编辑2

如果用户所属的群组/房间数量不断增加,则上述示例可能无法很好地扩展。

在这种情况下,每个用户都可以加入个人订阅源(即加入以用户GUID命名的订阅源)。我们会跟踪每个与组关联的用户。当消息发送到该组时,我们将迭代这些用户并向每个提要发布消息。