每个连接的生命周期仅限于用户在给定页面上花费的时间。当他们导航到另一个页面时,就会建立新的连接。此外,如果用户打开了多个选项卡或浏览器窗口,他们将拥有多个连接 ID。我认为您不想尝试在其预期生命周期之外保留连接 ID。
在我处理的类似场景中,我们在连接时存储连接 ID,并在断开连接时删除它们。当需要将消息发送给给定用户时,我们将其发送给他们的所有connectionId。这可确保消息将传递到所有选项卡/窗口。
EDIT 1以下是对@Saurabh评论的回应:
考虑中心的范围以及其他类和客户端的范围。集线器的作用是促进浏览器和服务器之间的通信。虽然可以在中心内完成大量工作,但我认为最好将通信之外的大部分范围移至其他地方。
客户端知道它刚刚重新加载了页面,因此它是做出这是重新连接事件决定的良好候选者。
_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)
}
}
你可以用很多不同的方式来剥皮。客户端也可以拥有记忆室的范围,而不是服务器端存储库。
EDIT 2
如果用户所属的组/房间的数量不断增加,则上面的示例可能无法很好地扩展。
在这种情况下,每个用户都可以加入个人提要(即加入以用户的 GUID 命名的提要)。我们将跟踪隶属于某个组的每个用户。当消息发送到该组时,我们将迭代这些用户并向每个提要发布消息。