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); }
}