首页 > 解决方案 > SignalR Core 跟踪连接的用户

问题描述

我有一个 ASP.NET Core 3.1 SignalR 集线器。

我想在多线程环境中跟踪连接的用户。

根据微软的说法,集线器是暂时的,因此不应在其上存储任何状态。

下面是我的 Hub 类:

public class MyHub : Hub
{
    private static bool _isLocked;
    private static readonly object _syncRoot = new object();

    // I want to remove this state property
    private static readonly List<OnlineUser> _users = new List<OnlineUser>();

    public override async Task OnConnectedAsync()
    {
        if (!_isLocked)
        {
            lock (_syncRoot)
            {
                if (!_isLocked)
                {
                    _isLocked = true;

                    _users.Add(new Online User
                    {
                        ConnectionID = Context.ConnectionId,
                        UserName = ""
                    });

                    _isLocked = false;
                }
            }
        }
    }
}

我还尝试了以下将在 Hub 中引用的静态类:

public static class OnlineUsers
{
    private static List<OnlineUser> Users = new List<OnlineUser>();
}

public class MyHub : Hub
{
    public override async Task OnConnectedAsync()
    {
        // code omitted for brevity
        OnlineUsers.Users.Add(new OnlineUser
        {
            ConnectionID = Context.ConnectionId,
            UserName = ""
        });
    }
}

我还找到了可以使用并发字典的示例,但这将再次将状态存储在集线器上: private static readonly ConcurrentDictionary<string, OnlineUser> _users;

推荐的方法是什么,因为除了您需要自己跟踪之外,我在 Microsoft 自己的文档中没有看到任何指南。

标签: asp.net-core-signalr

解决方案


我通过在集线器引用的单独静态类中使用静态并发字典解决了这个问题。


推荐阅读