SignalR -保持更新的ConnectionID
本文关键字:ConnectionID 更新 SignalR | 更新日期: 2023-09-27 18:12:03
我正在用asp.net MVC编写一个相当大的web系统,它涉及根据用户订阅的内容实时发送数据给许多用户。
我和我的团队决定使用SignalR,我负责在系统中实现它。
在本例中,用户选择要加入的组,然后选择要处理的1件事。
为此,我将所有用户保存在DB中。我将使用SignalR组来处理第一个类别,当我需要将消息推送到特定用户(对于他选择的其他事情)时,我将从DB获取他的ConnectionID。
问题在于—每次刷新页面时(例如,当用户选择要加入的组时),他都会获得一个新的connectionID。现在他不会看到推送给他的任何东西。
我看到在SignalR测试版,并在版本2(我只有1.1.1在我正在工作的计算机上),你可以让你自己的IUserIdProvider (IUserIdPrefixGenerator在测试版),或IUserConnectionIdFactory等。所以我可以给他我想让他拥有的,但我的SignalR版本中似乎没有这些。
有许多方法可以解决这个问题,但可能最简单的方法之一是将新的连接id与用户关联(可能他们仍然在不同的选项卡中打开另一个连接)。这可以使用IP地址、用户代理、报头或位置的任何组合来完成。另一个很好的选择是使用会话,或者只是一个简单的标识符cookie(这或多或少就是会话所要做的)。
我经常使用guid,然后在创建新的标识符cookie时在数据库中创建一个表。每次用户"刷新"或打开一个新选项卡时,cookie都可以在JS中读取并与hub.connect()
一起发送。然后,您可以在新的连接id和现有标识符cookie之间创建关联。
我强烈建议找出一种不同的方法来维护用户的持久的连接。通常,我将所有用户连接id存储在并发字典中,以允许线程安全访问集合。每当发生断开连接事件时,我就从字典中删除用户,每当发生连接事件时,我就添加用户。
SignalR将为您管理用户的连接。对于你来说,在数据库中这样做,并与SignalR不同步,会规避许多使其正确工作的机制。
private readonly static Lazy<App> _instance = new Lazy<App>(
() => new App(GlobalHost.ConnectionManager.GetHubContext<AppHub>().Clients));
private readonly ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>(StringComparer.OrdinalIgnoreCase);
private IHubConnectionContext Clients { get; set; }
public App(IHubConnectionContext clients)
{
Clients = clients;
}