C# ASP.NET MVC-获取用户的登录状态

C# ASP.NET MVC-获取用户的登录状态,c#,asp.net-mvc,C#,Asp.net Mvc,在我的应用程序中,我想检查某个特定用户是否登录,这样我就可以显示一个状态,表明该用户对另一个用户是“在线”还是“离线”。这个问题不是关于对用户进行身份验证,而是关于获取用户的身份验证状态 我将如何实现这一目标?我认为一个选择是使用一些实时解决方案。例如 当用户登录时,您将其连接到集线器。OnConnected()操作保存其状态。然后OnDisconnected()从“OnlineRepository”中删除 使用示例更新 下面是我在asp.NETMVC5应用程序中如何做到这一点的 包含单个用户

在我的应用程序中,我想检查某个特定用户是否登录,这样我就可以显示一个状态,表明该用户对另一个用户是“在线”还是“离线”。这个问题不是关于对用户进行身份验证,而是关于获取用户的身份验证状态


我将如何实现这一目标?

我认为一个选择是使用一些实时解决方案。例如 当用户登录时,您将其连接到集线器。OnConnected()操作保存其状态。然后OnDisconnected()从“OnlineRepository”中删除

使用示例更新 下面是我在asp.NETMVC5应用程序中如何做到这一点的

  • 包含单个用户的模型类,如:

    
        public class SingleConnection 
        {
            public SingleConnection()
            {
                ConnectionId = new List();
            }
            public string Id { get; set; }
            public List ConnectionId { get; set; }
        }
    
  • 一个连接映射类,用于帮助添加/删除和从列表中获取用户

    
        public class ConnectionMapping
        {
            private readonly List _connections = new List();
            public int Count
            {
                get
                {
                    return _connections.Count;
                }
            }
            public void Add(string key, string connectionId)
            {
                lock (_connections)
                {
                    var sn = _connections.Where(x => x.Id == key).FirstOrDefault();
                    if (sn != null) // there is a connection with this key
                    {
                        _connections.Find(x => x.Id == key).ConnectionId.Add(connectionId);
                    }
                    else
                    {
                        _connections.Add(new SingleConnection { Id = key, ConnectionId = new List { connectionId } });
                    }
                }
            }
            public List GetConnections(string id)
            {
                var con = _connections.Find(x => x.Id == id);
                return con != null ?  con.ConnectionId : new List();
            }
            public List AllConnectionIds() 
            {
                List results = new List();
                 var allItems = _connections.Where(x => x.ConnectionId.Count > 0).ToList();
                 foreach (var item in allItems)
                 {
                     results.AddRange(item.ConnectionId);
                 }
                 return results;
            }
            public List AllKeys() 
            {
                return _connections.Select(x => x.Id).ToList();
            }
            public void Remove(string key, string connectionId)
            {
                lock (_connections)
                {
                    var item = _connections.Find(x => x.Id == key);
                    if (_connections.Find(x => x.Id == key) != null)
                    {
                        _connections.Find(x => x.Id == key).ConnectionId.Remove(connectionId);
                        if (_connections.Find(x => x.Id == key).ConnectionId.Count == 0)
                        {
                            _connections.Remove(item);
                        }
                    }
                }
            }
        }
    
    • 在我的中心班
  • In_Layout.cshtml

    
    // reference scripts
    // add a callback or the OnConnected() Will not fire
    chat.client.clientconnected = function (id,active){
    /*
    this will be called everytime a user connect or disconnect to the hub
    */
    }
    $.connection.hub.start();
    
现在,我可以实时访问所有在线用户。
注意:这是一种内存解决方案。其他解决方案包括


希望这有助于…

我将创建自己的系统来定义您的“活动”用户:

  • 您可以使用类中存储的词典跟踪用户
  • 在基本控制器中(因为它将为任何 客户端请求)将当前用户插入缓存字典 通过调用KeepTrackActiveUsers方法
  • 将SetInactiveUser方法添加到注销方法中
{

专用字典用户
{
得到
{ 
if(缓存[“ActiveUsers”]==null)
缓存[“ActiveUsers”]=新字典();
返回缓存[“ActiveUsers”];
} 
设置{Cache[“ActiveUsers”]=value;}
}
私有void KeepTrackActiveUsers()
{
ActiveUsers[CurrentUserId]=DateTime.Now;
}   
私有常量int expirationTime=600;
私有IEnumerable GetActiveUsers()
{       
DateTime now=DateTime.now;
ActiveUsers=ActiveUsers
.Where(x=>now.Subtract(x.Value).TotalSecondsx.Key,x=>x.Value);
返回ActiveUsers.key;
}
私有void SetInactiveUser()
{
ActiveUsers.Remove(CurrentUserId);
}
//待定义
私有int CurrentUserId
{
获取{返回默认值(int);}
}

我认为没有一个内置字段可用于此操作。我建议您在数据库中的
AspNetUsers
表中创建一个自定义布尔字段。登录时将其设置为true,注销时将其设置为false。@DrewKennedy如果有人没有实际注销,而是关闭选项卡或浏览器,则该选项有效,或者avigates到另一个网站?这是我提出这个建议时考虑到的一个限制。答案是我非常怀疑。这可能是通过JavaScript完成的,但我不能提供一个明确的答案。@DrewKennedy现在你提到JavaScript,如果用户是“活跃”的,我可能不得不沿着跟踪的路线做一些事情解决这个问题。类似于让你退出30分钟不活动状态的网站,我不能确定,但如果他们使用WebSocket(例如SignalR),我不会感到惊讶。感谢你的建议,以及@DrewKennedy,我会关注它!好的,我现在在这里添加一个简单的解决方案,让你知道从哪里开始。

// reference scripts
// add a callback or the OnConnected() Will not fire
chat.client.clientconnected = function (id,active){
/*
this will be called everytime a user connect or disconnect to the hub
*/
}
$.connection.hub.start();
private Dictionary<int,DateTime> ActiveUsers
{
    get 
    { 
      if(Cache["ActiveUsers"] == null)
        Cache["ActiveUsers"] = new Dictionary<int,DateTime>();
      return Cache["ActiveUsers"];
    } 
    set { Cache["ActiveUsers"] = value; }
}

private void KeepTrackActiveUsers()
{
    ActiveUsers[CurrentUserId] = DateTime.Now;
}   

private const int expirationTime = 600;   
private IEnumerable<int> GetActiveUsers()
{       
    DateTime now = DateTime.Now;
    ActiveUsers = ActiveUsers
        .Where(x => now.Subtract(x.Value).TotalSeconds < expirationTime)
        .ToDictionary(x => x.Key, x => x.Value);
    return ActiveUsers.Keys;
}

private void SetInactiveUser()
{
    ActiveUsers.Remove(CurrentUserId);
}

//to be defined
private int CurrentUserId
{
    get { return default(int); }
}