Ich denke, eine Option besteht darin, einige Echtzeit-Lösungen zu verwenden. SignalR zum Beispiel. Wenn sich ein Benutzer anmeldet, verbinden Sie ihn mit dem Hub. OnConnected() Aktion seinen Zustand speichern. Dann OnDisconnected() aus "OnlineRepository" entfernen.
Update mit Beispiel Hier ist, wie ich das in einer asp.Net Mvc 5 App gemacht habe.
Eine Modellklasse, die sich wie eine einzige Benutzer hält:
public class SingleConnection
{
public SingleConnection()
{
ConnectionId = new List();
}
public string Id { get; set; }
public List ConnectionId { get; set; }
}
Eine Verbindung Mapping-Klasse, die in das Hinzufügen/removeing hilft und bekommen einen Benutzer aus der Liste
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();
Jetzt mit diesem erhalte ich in Echtzeit für alle Benutzer, die online sind.
Hinweis: Dies ist eine InMemory-Lösung. Andere Lösungen sind here
Hope this helps ...
Ich glaube nicht, gibt es eine eingebaute Feld, die dafür verwendet werden können. Ich würde empfehlen, ein benutzerdefiniertes boolesches Feld in Ihrer Datenbank in der Tabelle 'AspNetUsers' zu erstellen. Setzen Sie es auf wahr, wenn sie sich einloggen, und auf falsch, wenn sie sich abmelden. –
@DrewKennedy würde das funktionieren, wenn sich jemand nicht physisch abmeldet, sondern stattdessen die Registerkarte oder den Browser schließt oder zu einer anderen Website navigiert? – RoyalSwish
Das war eine Einschränkung, die ich im Sinn hatte, als ich das vorschlug. Die Antwort ist, dass ich es sehr bezweifle.Dies muss etwas mit JavaScript sein, aber ich kann keine feste Antwort geben. –