wer ist online + private nachrichten
-
Hallo Leute!
Wie implementiert man diese zwei Punkte (wer ist online und private nachrichten) am effektivsten? (PHP + MySQL)
das Problem:
mehrere tausend nutzer sind online
nicht jeder tut aber etwas, sondern jeder logt sich am anfang ein und tut dann nur alle heiligen zeiten mal auf einen link klicken...wie macht man es jetzt am besten, dass man alle user sehen kann die online sind?
wie erkenne ich, wer online ist?jeder user kann ja einfach den browser schliessen anstatt sich auszuloggen.
jeder user kann stundenlang keine neue seite aufrufen und ist trotzdem eingeloggt.meine Idee: ein dummy-frame wird alle 20 minuten reloaded und sagt der datenbank: 'Hallo, der User mit ID x ist immer noch da'.
das das ist n bisschen lahm, wenn das n paar tausend leute machen
gleiches problem bei privaten nachrichten... alle 10 minuten nachschauen ob neue nachricht da ist?
hier koennte man mit einer proxy tabelle arbeiten in der nur UserID und ID der nachricht stehen -> wenn der user eine nachricht erhalten hat, muss diese aus einer anderen tabelle auslesen. so gehen die vielen abfragen nur auf eine minimale tabelle...naja, im grunde frage ich mich, wie das die ganz grossen machen...
wie wird sowas normalerweise implementiert?
-
Das mit "wer ist online" ist wohl meist so, wie mit Sessions, also einfach mit einer Gültigkeitsdauer von z.B. einer halben Stunde. (Also eher ein welcher User surft gerade auf dieser Seite) Wenn ein User halt ne halbe Stunde lang nichts macht gilt er einfach nicht mehr als online. Falls dir das nicht reicht musst du eben deine Dummy-Frame Lösung nehmen. Von der Performance her dürfte das auch net so schlimm sein, wenn alle zehn Minuten mal eine Seite neu geladen wird, auf der zudem ja auch (fast) nichts draufsteht.
Wenn du dich bei den PN nicht damit zufrieden gibst, dass immer nur bei einem Seitenaufruf (so wie z.B. in vielen Foren) PN-Benachrichtigungen kommen kannst du das ja gleich mit in den Dummy-Frame mit rein packen (ist dann ja gar kein Dummy-Frame mehr )
-
aeh...
das ganze soll fuer mehrere tausend besucher sein.
ka. wieviele... momentan stehen etwa 2000-3000 user in der datenbank (tendenz stark steigend)wenn ich denke dass etwa 2000 user online sind... und alle 10 minuten kommen n paar datenbank abfragen von jedem user, so macht das 3,3 datenbank abfragen in einer sekunde (wenn jeder user nur 1 abfrage machen wuerde. tatsaechlich brauche ich aber 2 -> einmal private message und einmal 'ich bin noch online' - das 'ich bin noch online' koennte man alle halben stunden machen, aber trotzdem sind mir das zuviele abfragen dafuer, dass niemand etwas tut)
das ganze ist eine projektverwaltung: es melden sich also alle leuten in der frueh an, und steigen erst am abend wieder aus. es sind also immer sehr viele leute online - nur machen die meisten nichts.
ein halbstuendiger logout geht deswegen nicht...
technisch gesehen ist es einfach das zu realisieren. ein dummy frame und die sache ist erledigt. nur leider wird das die server nicht freuen wenn die zugedonnert werden mit SQL Queries obwohl niemand etwas macht.
es geht hier also darum wie man es effizient loesen kann...
wie teuer kommt es denn wenn man 3 mal pro sekunde ein
select id from messages where uid=$uid
macht, wenn messages aus 2 feldern uid und id besteht?und wie teuer kommt es, wenn man jede sekunde 1 folgendes query losschickt:
update online_user set online=now() where uid=$uidwuerde das den servern ordentlich zusetzen?
was wuerde seien wenn sich die userzahl verdoppelt?bitte auch daran denken: die server sind nicht nur dazu da um diese queries zu verarbeiten, sondern haben genug zu schwitzen wenn die user irgendwelche seiten aufrufen...
-
1.) Falls der User etwas macht kannst du ja mit dem Reload aussetzen!
2.) Falls dir JS nichts ausmacht könntest du auch den Logout per onUnload machen (oder habe ich das gerade falsch in Erinnerung) evtl. bei non JS Browser die andere Variante. Aber was ist, wenn dann der Browser abstürzt? Dann würde der User wohl fälschlicherweise eingeloggt bleiben (liese sich mit dem zusätzlichen Timeout lösen
3.) Was fängst du mit dem ganzen Who is online nachher an, wenn das eine Liste mit ein paar Tausend Leuten ist
-
flenders schrieb:
1.) Falls der User etwas macht kannst du ja mit dem Reload aussetzen!
nicht gut, die queries muessen trotzdem kommen
und selbst wenn, wie gesagt: die meisten leute sind 'idle'2.) Falls dir JS nichts ausmacht könntest du auch den Logout per onUnload machen (oder habe ich das gerade falsch in Erinnerung) evtl. bei non JS Browser die andere Variante. Aber was ist, wenn dann der Browser abstürzt? Dann würde der User wohl fälschlicherweise eingeloggt bleiben (liese sich mit dem zusätzlichen Timeout lösen
jo, browser absturz, netzausfall, server error oder einfach: PC wird abgedreht ohne das fenster vorher zu schliessen...
wie sollte das timeout dann ablaufen?
5 stunden lang keine aktion?
ne, sowas ist zu ungenau....3.) Was fängst du mit dem ganzen Who is online nachher an, wenn das eine Liste mit ein paar Tausend Leuten ist
das ganze ist ne projektverwaltung.
user sehen andere user die an gleichen projekten mitarbeiten
projektleiter sehen alle user der projekte wo sie leiter sind
admin sieht alle user in allen seinen projekten
etc.interessant ist es hauptsaechlich fuer die einzelnen projektleiter -> jeder sieht dann hoechten 10-20 user.
klar, fuer den root waere das overkill
-
Also entweder die User müssen sich explizit ausloggen und du hast evtl. Leichen drin, oder die zusätzliche Server-Last. Wie soll das denn rein technisch gesehen anders gehen? Entweder immer wieder nachschauen bzw. vom User her sagen, dass man noch da ist oder vertrauen, dass der User sich ausloggt.
Und an die PM kommst du auch nur durch Anfragen an den Server oder ganz evtl. per Java und Sockets o.ä. - aber da habe ich keine Ahnung
-
Ich maches so.
In der USERTABELLE habe ich ein Zeitfeld (REFRESH).
In dieses schreibe ich bei reload NOW() rein.
Auf dem Server liegt ein Daemon der jede Minute eine Abfrage auf
setze alle Datensätze auf ausgeloggt wo REFRESH < 10 Min (ODer ein beliebiger Wert von dir) ist.
Dadurch brauchst du nur über den USERTABLE gehen und alle anzeigen wo der Login auf 1 steht (0 ist ausgeloggt)
Wichtig sind aber hier die MYSQL-Parameter.
SELECT geht vor INSERT oder UPDATE. Sollte ein INSERT/UPDATE derzeit nicht gehen merkt sich MYSQL dieses Query und führt es erst aus wenn Zeit ist.
Da gibt es einen Configwert der die Anzahl der QUERY angibt. Diesen muss man erhöhen wenn man viele INSERT/UPDATE macht.
Normalerweise wartet der QUERY bis der UPDATE/INSERT ausgeführt wird. Dies kann man damit verhindern. Da es sich nur um ein UPDATE auf NOW() handelt muss man hier nicht warten sondern kann im Code weiter gehen.
Ich habe so einen Chat gebaut der auch funzt.
-
Private Nachrichten sollten nicht so das Problem sein... eine Tabelle mit
PMid senderid empfaengerid nachricht
erstellen und dann halt ein
"Sie haben"
'SELECT COUNT(empfaengerid) AS anz_nachrichten FROM pmtable WHERE empfaengerid = $userid'
"private Nachrichten"oder so machen
anschauen, löschen, antworten und schreiben geht ähnlich