2016-04-11 21 views
2

In meiner Anwendung möchte ich überprüfen, ob ein bestimmter Benutzer angemeldet ist oder nicht, damit ich einen Status anzeigen kann, der besagt, dass dieser Benutzer entweder "online" ist oder "offline" zu einem anderen Benutzer. Diese Frage lautet nicht über die Authentifizierung eines Benutzers, nur über den Authentifizierungsstatus eines Benutzers.ASP.NET MVC - Abrufen des Anmeldestatus eines Benutzers

Wie würde ich das erreichen?

+0

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. –

+0

@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

+0

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. –

Antwort

3

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); 
            } 
           } 
          } 
         } 
        } 
    
    • In meiner Hub-Klasse
    
    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 ...

+0

Danke für den Vorschlag, sowie @DrewKennedy, ich schaue hinein! – RoyalSwish

+1

Ok, dann werde ich hier eine einfache Lösung hinzufügen, damit Sie wissen, wo Sie anfangen sollen. –

+0

Dafür bin ich sehr dankbar, vielen Dank! – RoyalSwish

0

Ich würde mein eigenes System erstellen zu definieren, was sind Ihre „aktive“ Benutzer:

  • Sie den Überblick über Ihre Benutzer mit einem halten Wörterbuch in der System.Web.Caching.Cache Klasse gespeichert.
  • In Ihrem Basis-Controller (weil es für jede Client-Anforderung instanziiert werden würde) fügen Sie den aktuellen Benutzer in Ihr zwischengespeichertes Wörterbuch ein, indem Sie die KeepTrackActiveUsers-Methode aufrufen.
  • Fügen Sie Ihrer Logout-Methode die SetInactiveUser-Methode hinzu.

{

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