In my application, I would like to check whether or not a particular user is logged in or not so I can display a status saying that that user is either "online" or "offline" to another user. This question is not about authenticating a user, only about getting the authentication status of a user.
How would I go about achieving this?
I think an option is to use some real-time solutions. SignalR for example. When a user logs in , you connect it to the hub. OnConnected() action save its state.Then OnDisconnected() remove from "OnlineRepository".
Update with example Here is how I did this in a asp.Net Mvc 5 app.
A Model class that holds a single user like:
public class SingleConnection { public SingleConnection() { ConnectionId = new List(); } public string Id { get; set; } public List ConnectionId { get; set; } }
A connection mapping class that helps in adding/removeing and getting a user from list
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); } } } } }
private void IsActive(string connection, bool connected) { Clients.All.clientconnected(connection, connected); } public override Task OnConnected() { string name = Context.User.Identity.Name; _connections.Add(name, Context.ConnectionId); IsActive(name, true); return base.OnConnected(); } public override Task OnDisconnected(bool stopCalled) { string name = Context.User.Identity.Name; _connections.Remove(name, Context.ConnectionId); IsActive(name, false); return base.OnDisconnected(stopCalled); } public override Task OnReconnected() { string name = Context.User.Identity.Name; if (!_connections.GetConnections(name).Contains(Context.ConnectionId)) { _connections.Add(name, Context.ConnectionId); } IsActive(name, false); return base.OnReconnected(); }
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();
Now with this I get in realtime all users that are online.
Note: This is an InMemory solution. Other solutions are here
Hope this helps...
I would create my own system to define what are your "active" users:
{
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); }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.