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版本中似乎没有这些。

SignalR -保持更新的ConnectionID

有许多方法可以解决这个问题,但可能最简单的方法之一是将新的连接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;
    }