Ověření, zda je uživatel online + jejich součet

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
sumiisakua
Člen | 36
+
0
-

Rád bych se s Vámi poradil ohledně ověření, zda je uživatel online či nikoliv.

V hlavě mám dva způsoby řešení.

1. Při přihlášení uživatele proběhne sqlUpdate, který do tabulky online vloží jeho ID.
Při kliknutí na tlačítko odhlášení ho smaže. Při zavření prohlížeče nikoliv.

Klady: Uživatel se nemusí stále přihlašovat při návštěvě webu.
Zápory: Mám zkreslený součet uživatelů online pokud se neodhlásí → nesmaže se záznam z DB.


2. Při přihlášení uživatele proběhne sqlUpdate, který do tabulky online vloží jeho ID.
Při kliknutí na tlačítko odhlášení ho smaže. Při zavření prohlížeče ho také smaže.

Klady: Součet uživatelů online je přesný.
Zápory: Uživatel se musí stále přihlašovat při návštěvě webu.

Editoval sumiisakua (13. 2. 2012 16:57)

Jan Endel
Člen | 1016
+
0
-

Tahle funkce jestli je uživatel online se dělá většinou tak, že si do databáze nebo jiného úložiště člověk ukládá čas posledního kliku a pokud od posledního kliku uběhne náky konkrétní čas (typicky 5 minut) je uživatel považován ve stavu offline.

Tohle nemá moc s přihlašováním nic co společného. (kromě přidání jednoho řádku do login funkce)

sumiisakua
Člen | 36
+
0
-

pilec: Díky za názor. Tenhle způsob mě nenapadl, ale nějak se mi nezamlouvá.
Stále musim kontrolovat, jestli uživatel kliká + dělat dotaz na db, že je online.

Což mě přivádí k dalšímu dotazu:
Nyní je mazání stavu online závislé na uživatelově akci. Jak ale smazat online stav z db, bez kliknutí uživatelem? Tedy automaticky pomocí php?

Melmen
Člen | 132
+
0
-

sumiisakua napsal(a):

Tedy automaticky pomocí php?

To by šlo přes cron. Nastavit ho třeba na 10 minut, a on automaticky vykoná požadovanou akci.

Jinak k tématu, řeším to jak říká pilec
V tabulce users mám sloupec last_activity, který v BasePresenteru aktualizuji – tedy při každém kliku uživatele.
Pro výpis online uživatelů používám porovnání času last_activity a aktuálního času. Pokud je diference <= 5 minut, je online :)

Jan Endel
Člen | 1016
+
0
-

@sumiisakua: Co se ti nepozdává, tvé řešení taky požaduje, aby jsi se koukal do databáze jestli je online nebo ne. Taky je potřeba promyslet, kde všude to chceš zobrazovat.

sumiisakua
Člen | 36
+
0
-

@Melmen, pilec: Takže pokud to dobře chápu, tak máte v BasePresenter, nějakou funkci updateActivity(), která se zavolá tzv. vždy?

Editoval sumiisakua (13. 2. 2012 19:32)

Jan Endel
Člen | 1016
+
0
-

Pokud to nechceš řešit při každém kliku nebo se ti to zdá jako příliš velký záhul pro databázi. Můžeš si udělat javaskriptový časovač, co toto zavolá ajaxem jen co nějaký časový interval (co 4 minuty třeba). Otázkou pak je jaký je to typ webových stránek, jestli to třeba není blog, kde uživatel čumí na jednu stránku i desítky minut.

Tomáš Votruba
Moderator | 1114
+
0
-

sumiisakua napsal(a):

@Melmen, pilec: Takže pokud to dobře chápu, tak máte v BasePresenter, nějakou funkci updateActivity(), která se zavolá tzv. vždy?

Tak tak, řešení na 3 řádky např. ve startup:

class BasePresenter extends Nette\Application\UI\Presenter
{
	public function startup()
	{
		parent::startup();
		if($this->user->loggedIn) {
			$this->models->user->updateActivity($this->user->id);
			// v modelu pak: $this->database->user($this->user->id)->update(array("lastActivity" => new DateTime));
		}
	}
}

Editoval Schmutzka (13. 2. 2012 19:40)

Melmen
Člen | 132
+
0
-

Nevím jestli je to košér, ale funguje mi to :) V basePresenteru zjistím jestli je přihláše, a pokud ano, pošlu dotaz. Celé to mám v metodě beforRender().

      if ($user->isLoggedIn()) {
	  $model = $this->model->user->fetch()->where('id', $user->getId());
	  $datetime = new \Nette\DateTime;
	  $data['last_activity'] = $datetime;
	  $model->update($data);
}

EDIT:: O chvilku pozdějc :)

BTW, jakej je rozdíl řešit to ve startup() místo v beforRender()?

Editoval Melmen (13. 2. 2012 19:48)

sumiisakua
Člen | 36
+
0
-

Moc díky všem :)

Melmen: V době, kdy se to provede. Stratup jde na řadu jako první. beforRender je předposlední, jelikož po něm už je jen render().

Jan Endel
Člen | 1016
+
0
-

Je lepší to řešit v beforeRender, poněvadž třebas mám v aplikaci funkci která se redirektuje přeš tři presentery (příklad). A tak by se i dotaz zavolal třikrát v rozmezí milisekund ⇒ zbytečné.