2013-09-27 3 views
6

Ich implementiere eine Session-Struktur.So gehen Sie mit der offenen Sitzung um

Ich habe eine ConcurrentDictionary auf der Serverseite an alle <SessionId, UserSession> Paare halten.

Wenn eine neue Verbindung hergestellt wird, wird je nach der RememberMe Option ein Cookie einem Client-Browser, perm oder temp zugewiesen.

Wenn Clients die LogOut Funktion aufrufen, wird die Sitzung aus dem Wörterbuch entfernt.

Wenn jedoch der Client-Browser einfach geschlossen oder abgestürzt ist und ein Cookie verloren gegangen oder abgelaufen oder gelöscht wurde, verbleibt das serverseitige Sitzungsobjekt im Speicher im Wörterbuch und wird zu einem Ghost. Mit der Zeit werden sich diese Geister stapeln.

Meine Frage ist, wie man das Design verbessert, so dass die toten Sitzungen nach Ablauf gelöscht werden können?

Ich dachte daran, einen Timer-Dienst zu machen, der einen Reinigungsplan ausführt, aber es fühlt sich nicht elegant an. Gibt es eine einfachere Möglichkeit, dies zu tun, ohne von einem externen Dienst abhängig zu sein?

+1

Es wäre besser, einen Cache mit einem rollenden Begriff zu verwenden oder die Session_End-Methode zu behandeln. Was speichern Sie in UserSession? – zimdanen

+0

Es gibt keine zuverlässige Session_End-Methode, die behandelt werden kann, wenn der Client-Browser abstürzt, dann endet er einfach dort, ohne zurück zum Server zu sprechen. Aber jetzt, wo du einen Cache erwähnt hast, habe ich eine Idee, ich kann eine Liste nach LastActive Zeit speichern. Immer wenn sich ein neuer Client anmeldet, kann er helfen, die früheste Sitzung in der Warteschlange zu überprüfen und zu entfernen, wenn sie abgelaufen ist. Jeder aktive Benutzer wird sich selbst in den hinteren Bereich der Warteschlange stellen, wenn er den Server anruft, um etwas zu tun. So wird er zur neuesten aktiven Person. – Tom

+0

Müssen Sie irgendwann Daten über alle eingeloggten Benutzer sehen? Wenn nicht, dann speichern Sie Ihre Daten einfach in der Sitzung (wenn Sie die Daten benötigen) und lassen Sie sie nach Ablauf der Sitzung wieder verschwinden. Das wird den Speicherdruck auch durch das Auslassen von Elementen aus der Sitzung bewältigen, wenn Druck besteht. Oder verwenden Sie HttpContext.Cache mit einem rollenden Timeout, sodass es nach einer festgelegten Zeit nach dem letzten Zugriff wieder verschwindet. (Im Prinzip keine Notwendigkeit, eigene zu rollen.) – zimdanen

Antwort

4

Ich habe ähnliche Situation in einem meiner Projekte.

statt Wörterbuch verwendet i-Cache mit einer kurzen absoluten Ablauf und Session-ID des Benutzers als meinen Cache-Schlüssel:

HttpContext.Current.Cache.Insert(sessionID, userEntity, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero); 

und in der Client-Seite, ich einen Ajax-Aufruf machen, alle 15 Sekunden, bis Benachrichtigen Sie den Server und erneuern Sie den Cache für diese Sitzungs-ID.

Wenn ein Benutzer das Browserfenster schließt, erhält der Server keine Benachrichtigung und die Sitzungs-ID des Benutzers wird automatisch abgelaufen.

+0

Danke, habe einige Suche nach der Idee, realisiert System.Runtime.Caching in .NET4 oben scheint der Weg zu gehen. http://bartwullems.blogspot.com.au/2011/02/caching-in-net-4.html – Tom

0

Ich beantworte meine eigene Frage nach ein paar Monaten. Wenn ich eine solche Struktur haben möchte, würde ich Microsoft SignalR verwenden. Weil es die Sitzungen für mich in Echtzeit steuert und viel mehr tut.

+0

Warum verwenden Sie weiterhin Sitzungen zur Authentifizierung von Benutzern? Diese Methode war eine brauchbare Lösung für die klassische ASP-Ära, aber nicht mehr. Sie sollten stattdessen die ASP.NET-Formularauthentifizierung in Erwägung ziehen, die in ASP ein bevorzugter Ansatz ist.NET Welt. – VahidN

2

Wenn Ihr Sitzungsstatus "InProc" ist, warum wenden Sie Ihren Code nicht einfach in Session_Start und Session_End an?

void Session_Start(object sender, EventArgs e) 
{ 
    //Add to ConcurrentDictionary 
} 

void Session_End(object sender, EventArgs e) 
{ 
    // Note: The Session_End event is raised only when the sessionstate mode 
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised. 

    //Remove from ConcurrentDictionary 
} 
Verwandte Themen