# Logout oder Fenster schliessen



## EuroCent (3. Juni 2007)

Hallo sitze vor folgendem Problem:

Wenn sich ein User bei mir Anmeldet und nach 5min den Browser schliesst ohne sich auszuloggen dann steht er weiterhin auf Online. Kommt er erneuert rein muss er sich anmelden da mein System mit session läuft, meine Session dauern solange an wie sein Browserfenster auf ist!

Gibt es nun eine Möglichkeit es zu realisieren das wenn der User XYZ bei seinem Browser auf schliessen geht das er automatisch ausgeloggt ist? Oder funktioniert das dann nicht!

Den normal würde mir reichen wenn sein Online Status nach dem er das Fenster geschlossen hat auf Offline steht und seine Letzte Aktion in Zeit gespeichert wird!

Wie kann ich das realisieren?

Danke euch


----------



## athx (3. Juni 2007)

Du könntest ein Cronjob schreiben, der alle 5 Minuten alle OnlineUser löscht.

lg


----------



## EuroCent (3. Juni 2007)

athx hat gesagt.:


> Du könntest ein Cronjob schreiben, der alle 5 Minuten alle OnlineUser löscht.
> 
> lg



Hä... und was soll mir das bringen dann werden auch die als Offline geführt die aber Online sind?

Ich möchte lediglich eigentlich auch nur abfangen das wenn jemand den schliessen button seines Fensters betätigt oder wie auch immer Offline gestellt wird...!

Hab es bei mir so:


```
<?
session_start();
$sid = session_id();
require("templates.php");

//Verbindungsdaten
$sqlhost = "localhost";
$sqluser = "xxx";
$sqlpass = "xxx";
$sqldata = "wms";
//Verbindung herstellen
mysql_connect($sqlhost, $sqluser, $sqlpass) or die("Verbindung fehlgeschlagen!");
//Selektieren der DB
mysql_select_db($sqldata) or die("Datenbank konnte nicht gefunden werden!");

//Eingeloggt
$sql = mysql_query("SELECT * FROM mitglieder WHERE usersess='".$_REQUEST['sid']."'");
	while($users = mysql_fetch_array($sql)) {
		$userid = $users['userid'];
		$username = $users['username'];
		$admin = $users['is_admin'];
		$mod = $users['is_mod'];
		$usersess = $users['usersess'];
		$lastlogin = $users['lastlogin'];
		$sesstime = $users['sesstime'];
		$group_id = $users['group_id'];
	}
	
	$tpl = &new dbbtpl('./templates/cache', './templates', 0);

		// Header-CSS	
		eval("\$css = \"".$tpl->get("css")."\";");
		//Header
		eval("\$header = \"".$tpl->get("header")."\";");
		//Footer
		eval("\$footer = \"".$tpl->get("footer")."\";");
?>
```


----------



## Luzie (3. Juni 2007)

Lenox hat gesagt.:


> Ich möchte lediglich eigentlich auch nur abfangen das wenn jemand den schliessen button seines Fensters betätigt oder wie auch immer Offline gestellt wird...!



Hallo

das geht nicht, das ist auch gut so. 

Du musst das über ein Insert- bzw. Update-Statement auf eine Tracking-Tabelle lösen. Hier setzt Du einen Zeitraum ein z.B. 5 Min., in dem der User möglicherweise keinen Klick auf Deiner Seite abgeben könnte. 

Jeder Klick, der innerhalb der Zeit erfolgt, setzt ein Update auf die Zeit der IP. Ist die Zeit überschritten (z.b. nach 5 Min), wird der Datensatz gelöscht und der nächste Klick, z.B. nach 6 Min. wird wieder ein Insert mit IP und Zeit.


----------



## athx (3. Juni 2007)

Sry, jetzt fällt mir wieder die effektivste Methode ein:

Du brauchst eine Tabelle "user_online" oder machst die Spalten der Tabelle woanderst rein ;-)

user_online:
id, int, 11, unsigned, not null, , auto_increment, primary, ,
userid, int, 11, unsigned, not null
time, int, 11, unsigned, not null,

config.inc.php

```
<?php
$USER_ON_TIME = 5*60; // Onlinezeit: 5 Minuten
?>
```

Script welches in dein Teil kommt, den nur eingeloggte zu sehen bekommen:

```
<?php
include('config.inc.php');
$min_time = time()-$USER_ON_TIME;

$sql = "SELECT * FROM `user_online` WHERE `userid` = '$userid' AND `time` > '$min_time' "; // USERID ist die Userid
$result = mysql_query($sql);

if(mysql_num_rows($result) < 1){
  $sql = "INSERT INTO `user_online`(`userid`, `time`) Values ('$userid', ' ".time()." ' )";
  mysql_query($sql);
}
else {
  $sql = "UPDATE `user_online` SET `time` = '".time()."' WHERE `userid` = '$userid'"; 
  mysql_query($sql);
}
?>
```

So, jetzt noch die Useronline Abfrage:

```
<?php
include('config.inc.php');
$min_time = time()-$USER_ON_TIME;

$sql = "SELECT * FROM `user_online` WHERE `time` > '$min_time'";
$result = mysql_query($sql);
$amount = mysql_num_rows($result);
echo "Zur Zeit sind {$amount} User online!";
?>
```


----------



## EuroCent (4. Juni 2007)

Nein mir geht es darum das User die sich nicht ausgeloggt haben sondern nur den Browser geschlossen haben das man da irgendwie überprüfen könnte ob er noch aktiv ist!

Den wenn ich mich einlogge und dann mein Fenster schliesse aus welchen gründen auch immer dann stehe ich solange Online bis ich mich einlogge und wieder auslogge!

Und genau das soll nicht passieren... hab mir eben gedacht sobald ein User sein Fenster schliesst das er automatisch ausgeloggt wird... aber wie realisiert man sowas?

Oder gibt es da eine einfache Methode dies einfacher zu gestalten

Ich hab eine Tabelle mitglieder da wird: userid, username, usersess, online, lastlogin und sesstime gespeichert

Hofffe man weiss nun was ich möchte


----------



## Flex (4. Juni 2007)

Ich würde bei jedem Aufruf einfach alle User die länger als X Minuten inaktiv waren (am Besten du erweiterst deine Tabelle um ein Feld lastaction) als offline kennzeichnen.

Nachteil ist halt, dass du bei jeder neuen Aktion das Feld aktualisieren müsstest.
Aber den ganzen Code könnte man ja bequem in eine Funktion packen, dann sollte das gehen.

Mit Browser schließen ist das so eine Sache, da PHP nicht alleine interaktiv reagieren kann. Da müsstest du also eine Verbindung mit JavaScript schalten, was wieder bei Usern, die kein JavaScript aktiviert haben, nicht funktioniert.


----------



## SaschaT (4. Juni 2007)

Lenox hat gesagt.:


> sobald ein User sein Fenster schliesst das er automatisch ausgeloggt wird... aber wie realisiert man sowas?



Hab sowas zwar noch nicht implementiert, aber ich eine Idee wäre, über den JavaScript-EventHandler _onclose_ einen HTTPXMLRequest mit der Logout-Anweisung abzusetzen.

Nachteile: 
-Funktioniert nur wenn der User JavaScript zulässt
-macht u.U. eine Browserweiche erforderlich (wegen unterschiedlichem Eventmodell von IE und FF)
-weiß nicht genau, ob der Ansatz so wirklich funktionieren kann


----------



## athx (4. Juni 2007)

Felix Jacobi hat gesagt.:


> Ich würde bei jedem Aufruf einfach alle User die länger als X Minuten inaktiv waren (am Besten du erweiterst deine Tabelle um ein Feld lastaction) als offline kennzeichnen.



Genau das habe ich versucht mit dem obigem PHP Script auszudrücken.



Felix Jacobi hat gesagt.:


> Mit Browser schließen ist das so eine Sache, da PHP nicht alleine interaktiv reagieren kann. Da müsstest du also eine Verbindung mit JavaScript schalten, was wieder bei Usern, die kein JavaScript aktiviert haben, nicht funktioniert.



onUnLoad hilft dir vll...

lg


----------



## KD3 (4. Juni 2007)

Du erstellst ein neues SQL Kommando der alle user und alle herausfiltert die z.B in der datenbank auf online sind und wenn z.B vom Zeitpunkt (von der einloggzeit die immer aktualisiert wird) <= 5 ist dann wird offline angezeigt! naja so muss es eigentlich gehen..

MfG
KD3


----------



## EuroCent (5. Juni 2007)

Danke erstmal

Gibt es auch eine Möglichkeit den Query


```
<?php
$online_time = 30; //Anzeige wielang ein Useronline ist für 30Sekunden
$time = time();
$min_time = ($time)-($online_time);

$last_time = mysql_query("SELECT * FROM mitglieder WHERE lastaction='".$min_time."'") or die(mysql_error()); //USERID ist die Userid
	while($row = mysql_fetch_array($last_time)) {
	
		$lastaction = $row['lastaction'];
		
		if($lastaction > $min_time) {
			mysql_query("UPDATE mitglieder SET lastaction='".$time."' WHERE userid='".$userid."'");
		} else {
			mysql_query("UPDATE mitglieder SET usersess='NULL', online='0', lastlogin='".$time."', sesstime='0'");
		}
	}
?>
```

zu Refreshen?

Zum beispiel das er alle 35sekunden abfragt statt 30sekunden? Da ja die 30sekunden für den ablauf des onlines bestimmt ist!

EDIT:

Irgendwie t das nicht so wie es sollte

Ich hatte es mir so gedacht das wenn jemand die Seite Aktualisiert beispiel nach 5min das er dann ausgeloggt ist, wenn der User aber nun das Fenster schliesst steht er ja immer noch als eingeloggt da


----------



## Luzie (5. Juni 2007)

Hallo

es ist doch nicht sicher, ob der User überhaupt das Fenster schließt. Viell. geht er auch für 2 Std. in die Mittagspause und ist weiterhin bei Dir online, tut aber nix auf der Seite. Dann kann es sein, dass er eine neue Adresse eintippt und damit weg ist etc. Du musst einfach mit Karenzwerten arbeiten. Wirklich sicher kannst Du nur sein, wenn er die Session löscht. 

Ich wollte nicht kontrolliert werden, wann ich mein Fenster schließe und was ich sonstwo noch mache. 

Hier ein Bespielscript, (ich glaube, das ist sogar mal hier im Forum gepostet worden, bin mir aber nicht ganz sicher), da werden diejenigen User herausgelöscht, die 1 Minute lang untätig waren. Innerhalb dieser Minute wird ein Update auf die Zeit gesetzt, ansonsten ein Insert eines neuen Datensatzes. Ist der Intervall von 1 Minute verstrichen, geht man davon aus, das der User weg ist und sein Datensatz wird gelöscht. 

Dies ist nur ein Beispiel, wie ich es machen würde. 
Andere Beispiele sind ja hier schon gepostet worden. 


```
<?php
session_start();
$server = "localhost"; 
$user = "root"; 
$pass = "passwort";
$database = "db";
$tab = "online";

$verbindung = @mysql_connect($server,$user,$pass)
    or die ("Keine Verbindung möglich");
    mysql_select_db($database, $verbindung)
    or die ("SQL-Fehler = ".mysql_error());
    
// Abfrage ob User registriert

$username = "";

if (isset($_SESSION["user"])){ 
        $username = $_SESSION["user"];
    }

// Variable anlegen, welche die IP zurückliefert (optional)
$ip = $_SERVER['REMOTE_ADDR'];

// löschen der entsprechenden Datensätze bei jedem Klick
// wenn der gespeicherte Zeitpunkt kleiner ist als der aktuelle Zeitpunkt minus 1 Minute

mysql_query("DELETE FROM
                $tab
            WHERE
                DATE_SUB(NOW(), INTERVAL 1 MINUTE) > Datum");

// auslesen, ob die angeforderte IP schon eingetragen ist

$wer_drin = "SELECT COUNT(*) as anzahl FROM online WHERE IP='$ip'";
list($ist_drin) = mysql_fetch_row(mysql_query($wer_drin));
if($ist_drin > 0) {

    // IP steht bereits in DB
    mysql_query("UPDATE $tab SET Datum = NOW() WHERE IP ='$ip'");
    } else {
     // ansonsten meuer Eintrag
            mysql_query ("INSERT INTO $tab
                        (IP, Datum, name)
                    VALUES
                        ('$ip', NOW(),'$username')");
    }
// anzeigen, wieviele User zur Zeit online sind
$wieviele = "SELECT COUNT(*) FROM $tab";
list($soviele) = mysql_fetch_row(mysql_query($wieviele));

echo "Zur Zeit online: ".$soviele."<br>";

// Auflistung der registrieren User. Hier filtere ich einfach die Namen raus. 
// Die nichtregistrieren User haben keinen Namen-Eintrag.

$sql = "SELECT name from $tab where length(name)>0";
  $rs = mysql_query($sql);
  $row = mysql_fetch_array($rs);
  $total = mysql_num_rows($rs);
  if($total == 0){
  echo "Zur Zeit keine registrierten User vorhanden!";
  } else {
        echo  "Zur Zeit registrierte User: ";
    do {
      echo $row[0]." ";
       }
       while ($row=mysql_fetch_array($rs));
  }
mysql_free_result($rs);
mysql_close($verbindung);
?>
```


----------



## EuroCent (5. Juni 2007)

Danke für die Prompte Antowrt

Hab das wie folgt gelöst:


```
<?php
//Ausgeloggt nach Zeit
$USER_ON_TIME = 5*60; // Zeit für Inaktivität (300Sekunden) 5Minuten
$min_time = time()-$USER_ON_TIME;

$sql_log = mysql_query("SELECT * FROM mitglieder WHERE usersess='".$_REQUEST['sid']."'");
	while($row = mysql_fetch_array($sql_log)) {
	
		if($row['lastaction'] < $min_time) {
			mysql_query("UPDATE mitglieder SET usersess='NULL', online='0', lastlogin='".time()."', sesstime='0' WHERE lastaction < '".$min_time."'");
		} else {
			mysql_query("UPDATE mitglieder SET lastaction='".time()."' WHERE usersess='".$_REQUEST['sid']."'");
		}
	
	}
?>
```

Doch nun ist noch das Problem wenn der User sein Fenster schliesst dann ist er ja immer noch als Eingeloggter User verzeichnet!

Gibt es da eine Lösung um dieses Problem zu beseitigen?
Oder muss ich dann so hin nehmen?

Den ich hätte es gern das nach den 5min egal ob der User sein Fenster zu oder gar noch online ist aber nix macht, das er auf den Offline Status gesetzt wird, seine session gelöscht wird


----------



## KD3 (6. Juni 2007)

Du kannst eigentlich auch im Hintergrund alle User abchecken lassen, also jeder der über der zeitspanne über ist bekommt seine session id gelöscht und im datenfeld "online" wird es auf 0 gesetzt bei allen dann sind die jenigen offline  Würde eigentlich gehen 

MfG
KD3


----------



## EuroCent (6. Juni 2007)

Hmm.... hab ich allerding schon getestet nur dann gibt es das Problem selbst nach ablauf der zeit sind die die nicht drunter fallen damit betroffen!

Ich dachte so in der art das man eine art Cronjob aufsetzt dafür um alle 5min den Cronjop aufzurufen!

Es sollte aber wenn möglich gehen das man im ACP die zeit die man begrenzt in den Cronjop verweissen kann so das er beispiel: nicht 5 sondern 10 min refresht

Ich hoffe das es irgendwie eine möglichkeit gibt dies zu vereinfachen!


----------

