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

Sau*_*ank 3 c# asp.net-mvc-4 signalr signalr-hub

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

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

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

and*_*des 5

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

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

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

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

客户端知道它只是重新加载了一个页面,因此它是一个很好的候选者,可以决定这是一个重新连接事件.

_chatHub.server.reJoinRooms();
Run Code Online (Sandbox Code Playgroud)

然后,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);
}
Run Code Online (Sandbox Code Playgroud)

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

$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)
       }
}
Run Code Online (Sandbox Code Playgroud)

你可以用许多不同的方式涂抹.客户端可以拥有记住房间的范围,而不是服务器端存储库.

编辑2

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

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