2008-10-29 8 views
6

Ich versuche, Benutzer zu protokollieren, wenn das Sitzungszeitlimit des Benutzers auftritt. Das Abmelden von Benutzern - in meinem Fall - erfordert die Änderung des "Online" -Status des Benutzers in einer Datenbank.
Ich dachte, dass ich in der Lage sein könnte, das Observer-Muster zu verwenden, um den Status der Benutzersitzung zu überwachen und einen Rückruf auszulösen, wenn die Sitzung abläuft. Der Name des Benutzers wird beibehalten, damit die Datenbank aktualisiert werden kann. Ich bin mir nicht sicher, wo ich auf der Sitzung beginnen soll. Kann ich einen Rückruf an das Timeout der Sitzung binden?PHP-Beobachter-Muster, um Benutzer zu protokollieren, wenn die Sitzung abläuft

Sind diese Dinge in alle verfügbaren Pear- oder Zend-Session-Pakete eingebaut? Ich werde alles nutzen, um dies zu ermöglichen!



UPDATE @ 16.33:
Was ist, wenn Sie ein System haben, in dem Benutzer miteinander in Wechselwirkung treten können (aber sie können nur mit Online-Benutzern interagieren)? Der Benutzer muss wissen, welche anderen Benutzer gerade online sind.

Wenn wir einfach überprüfen, ob die Sitzung bei jeder Seitenaktualisierung noch aktiv ist, wird der Benutzer nach einer Zeitüberschreitung an eine nicht eingeloggte Seite gesendet, die jedoch weiterhin als online im System aufgeführt ist.

Diese Methode wäre in Ordnung, außer dass, wenn wir die Sitzung abbrechen, verlieren wir die Informationen über den Benutzer, die verwendet werden könnten, um sie abzumelden.



UPDATE @ 16: 56:
rechts. Vielen Dank. Ich stimme zu ... irgendwie hässlich. Ich habe bereits eine langsame Abfrage des Servers, so dass es ziemlich einfach wäre, diese Methode zu implementieren. Es scheint nur so ein nützliches Feature für ein Session-Handling-Paket zu sein. Zend und PEAR haben beide Sitzungspakete.

Antwort

1

Warum möchten Sie das tun? Der übliche Ansatz besteht darin, jede vom Benutzer gesendete Anforderung zu überprüfen, wenn das Zeitlimit abgelaufen ist. Das bedeutet natürlich, dass der Status in Ihrer Datenbank nicht aktuell ist, da der Benutzer immer noch als eingeloggt angezeigt wird, obwohl das Timeout erreicht wurde.

Aber für praktische Zwecke ist das normalerweise egal.

0

hässlich, aber vielleicht tragfähige Vorschlag:

einen asynchronen Keep-Alive-Anforderer zu Seiten hinzufügen, die ihren letzten aktiven Zeitstempel aktualisiert. Sie können dann einen Cron-Job haben, der Benutzer als offline markiert, wenn sie einen letzten aktiven Zeitstempel haben, der älter als 20 Sekunden ist. Die Einstellung dieses Cron-Jobs, der jede Minute ausgeführt wird, würde den Trick bewirken. Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, etwas auszulösen, wenn die Sitzung eines Benutzers abbricht oder ihren Browser schließt.

2

Nehmen Sie den einfachsten Fall zuerst. Angenommen, Sie haben 1 Benutzer auf Ihrem System und möchten, dass ihre Sitzung eine Zeitüberschreitung aufweist und Sie eine genaue Meldung ihres Status wünschen. Der Benutzer war in 12 Minuten nicht auf einer Seite und das Sitzungszeitlimit ist auf 10 Minuten festgelegt. Eines von zwei Dingen wird passieren. Entweder werden sie in kurzer Zeit wiederkommen, oder sie werden es nicht tun. Wenn sie nicht wieder besuchen, wie wird das System jemals Code ausführen, um ihren Timeout-Status zu aktualisieren? Die einzige Möglichkeit * besteht darin, dass ein separater Prozess eine Statusaktualisierungsfunktion für alle Benutzer einleitet, die sich gerade im Status "in Sitzung" befinden.

Jedes Mal, wenn ein Benutzer Ihre Site aufruft, aktualisieren Sie eine Variable in der Datenbank, die ihre Sitzung mit der zuletzt aufgerufenen Zeit verknüpft. Erstellen Sie dann einen Cronjob, der jede Minute ausgeführt wird. Es ruft eine einfache Funktion auf, um den Sitzungsstatus zu überprüfen.Alle Sitzungen, die älter als die Zeitüberschreitung sind, werden auf den Status "Zeitüberschreitung" gesetzt. (Sie sollten auch den Tisch aufräumen, nachdem die zeitgesteuerten Sitzungen für eine Weile gesessen haben). Wenn Sie jemals einen Bericht über die Anzahl der angemeldeten Personen wünschen, fragen Sie nach allen Datensätzen, bei denen der Zeitpunkt des letzten Zugriffs später als der Start des Zeitüberschreitungsintervalls liegt.

"*" Es gibt andere Wege, aber für die Zwecke einer einfachen Webanwendung ist es nicht wirklich notwendig. Wenn Sie etwas komplizierteres als eine einfache Web-App haben, aktualisieren Sie Ihre Frage, um die spezifischen Anforderungen zu berücksichtigen.

+0

Statt der Cron, einen einfachen Benutzer überprüfen über die Logik der Seite (Suche nach Cookie, überprüfen Sie 'last_visited' Spalte auf Benutzer db Datensatz, etc). Wenn der Benutzer also beschließt, wieder aktiv zu werden, können Sie die Benutzerinformationen und -aktivitäten überprüfen und trotzdem weiterleiten, da die Header noch nicht gesendet wurden. –

2

liest Jedes Mal, wenn ein Benutzer eine Seite trifft, dass die Zeit in der Datenbank markiert, rufen Sie diese Spalte LastAccessed. Wenn der Benutzer auf den Abmeldebereich Ihrer Site klickt, können Sie diesen Wert auf null setzen. Beim Schreiben Ihrer Anfrage eine Liste von Benutzern zu finden, die gerade angemeldet sind, gehen Sie wie folgt vor:

SELECT * FROM Users WHERE LoggedIn=1 AND LastAccess > DATEADD(Minute,-20.GETDATE()) 

, die die Nutzer zurückkehren würde, die immer noch eine aktive Sitzung haben. Entschuldigen Sie die SQL, die wahrscheinlich nicht mit MySQL/PHP funktioniert, aber das sollte Ihnen eine allgemeine Idee geben.

0

Ich weiß, könnte dies eine ältere Frage, aber die „beste“ Antwort auf Ihre Frage ist hier: http://www.codeguru.com/forum/archive/index.php/t-372050.html

Hier ist, was es sagt: Die php.ini eine Einstellung namens sesison.save_path enthält bestimmt dies, wo PHP Dateien ablegt, die die Sitzungsdaten enthalten. Sobald eine Sitzung veraltet ist, wird sie bei der nächsten Garbage Collection von PHP gelöscht. Daher sollte ein Test für das Vorhandensein eines Feldes für diese Sitzung geeignet sein, um zu bestimmen, ob die Sitzung noch gültig ist.

$session_id = 'session_id'; 
$save_path = ini_get('session.save_path'); 

if (! $save_path) { 
$save_path = '.'; // if this vlaue is blank, it defaults to the current directory 
} 

if (! file_exists($save_path . '/sess_' $session_id)) { 
unlink($session_id); // or whatever your file is called 
}