09. september 2003 - 18:20Der er
25 kommentarer og 2 løsninger
Hvilke brugere er online.
Hej Eksperter
Jeg er ved at lave en funktion, som kan vise hvilke medlemmer der er online på et givent site. Jeg har et felt i min database, som bliver sat til "online" når man logger ind, og offline når man logger ud. Problemer er imidlertid, at jeg vil bruge global.asa til at sætte værdien "offline" når en bruger fx bare lukker browseren. Mit problem er, at når jeg i session_onEnd, vil opdateret feltet i databasen, kan jeg jo ikke bruge session("userid"), da den åbenbart er udløbet. Hvordan sulen, kan jeg så indentifisere hvilket medlem det er der logger ud ?
Du skal benytte Session_OnEnd som du selv foreslår, men du skal huske at selvom brugeren lukker sin browser ned, bliver Session_OnEnd ikke kaldt med det samme, men først når sessionen timer ud. Session Timeout kan du selv styre, men som default er den på 20 min. Jeg benytter selv Session.SessionID, til at identificere brugerene, men i princippet kan du benytte hvilken form for sessions variabel du ønsker, for disse variable bliver først renset _efter_ session_onend bliver kaldt... Håber det er beskrevet forståeligt nok :-)
Ja det lyder godt nok spooky... jeg kaster lige et udsnit af det jeg selv benytter:
Sub Session_OnStart ... SID = Session.SessionID username = "Guest" & Application("NumGuests") 'opdateres hvis brugeren logger ind... ... cn.Open strDSN
dayStr = Now cn.execute("INSERT INTO onlineUsers(SID, username) VALUES('" & SID & "', '" & username & "')") cn.Close Set cn = Nothing End Sub
Sub Session_OnEnd '****** opdater databasen med false cn.Open strDSN cn.execute("DELETE FROM onlineUsers WHERE SID = '"& Session.SessionID & "'") cn.Close Set cn = Nothing End Sub
Det du kan gøre er så at have et felt i din tabel over brugere der indeholder et sessionsID. Dette ID sørger du for at opdatere hvergang de logger ind. Når deres session udløber, opdaterer du som med ovenstående i tabellen, hvor sessionsID er lig det der timer ud. Evt post din kode, så kigger jeg på det...
Jeg kan godt se idéen i dit, men jeg vil helst holde det i én tabel, da jeg udskriver alle brugere på en liste, og så gerne bare vil vise om de er online eller ej.
Min kode:
Sub Session_OnStart
session.timeout = 20
End Sub
Sub Session_OnEnd
if session("login") = "true" then
Set conn = Server.CreateObject("ADODB.Connection") DSN = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" + Server.MapPath("../db/database.mdb") conn.Open(DSN) set opendb = conn
SQL = "UPDATE users SET online = false WHERE id = " & session("userid") conn.execute(SQL)
Det jeg mener, det er at du i din tabel users opretter et felt der hedder SessionID el.lign. Når brugeren logger på via dit login script, laver du en update, fx "UPDATE users SET SessionID = '" & Session.SessionID & "' WHERE username = '" & Request.Form("username") & "'"
I din Session_OnEnd laver du så følgende linie: "UPDATE users SET online = false WHERE SessionID = '" & Session.SessionID & "'"
Så er det næsten lig det jeg har lavet, pånær du laver en update istedet for en delete....
Lav blot en kolonne i tabellen med dato/tid for brugerens sidste login. Når dette er mindre end f.eks. 3 minutter siden, kan du angive brugeren som værende online.
If DateDiff("n", rs("SidsteLogin"), Now) < 3 Then 'Brugeren er online End If
'Udtræk online-brugere SQL = "Select Brugernavn From Brugere Where SidsteLogin > '" & DateAdd("n", -3, Now) & "'"
Jo, en del mere faktisk. Som standard timer en session først ud 20 min efter sidste sideanmodning. Desuden får du problemer, hvis brugeren har slået session-cookies fra. Slutteligt kan du sikkert ikke engang få lov at opdatere Access i Session On_End.
Glemte forresten at sige, at du naturligvis også skal opdatere dato/tid for brugerens sidste login f.eks. hvert 3. minut. Således vil en bruger aldrig stå som værende online, hvis vedkommende har været inaktiv i mere end 3 minutter.
Kan sagtens følge den idé med at benytte en dato/tid, men min holdning er, at så længe ens session er aktiv, er det også at tælle som en aktiv bruger på sitet. Man kan jo vælge at sætte Timeout til noget andet end 20 min. Men kan som sagt godt følge den anden idé, selvom jeg ikke er enig :-) Det jeg er mest modstander af, er at man hvergang der loades en side skal opdatere i DB'en, hvilket fra et designmæssigt hensyn ikke vil være optimalt, da det bruger unødigt CPU kraft på serveren. Der er ofte diskutioner om det med at opdatere Access fra global.asa, og der er aldrig nogen der bliver enige, for det afhænger meget af hvilken webserver det er, og hvorledes denne er sat op.... personligt har jeg endnu ikke oplevet problemer, men én gang skal jo være den første :D
Ang. point, skal du helt sikkert give point til den løsning du benytter - medmindre selvfølgelig du mener at du kan benytte den anden løsning til noget andet - pointene er helt op til dig selv, og jeg tvivler på der vil være sure miner :D
luzk -> Når en bruger lukker browseren, mener du altså, at vedkommende stadig skal betrages som online, når han/hun er nede og købe ind? Du skal da heller ikke opdatere tabellen ved hvert sideskift. Læs hvad der står:
"...skal opdatere dato/tid for brugerens sidste login f.eks. hvert 3. minut"
Det kan du gøre på flere måder. Når en bruger logger ind (enten manuelt eller automatisk) opdaterer du login-tidspunktet. Herefter kan du f.eks. opstille følgende betingelse for opdatering:
If Minute(Time) Mod 3 = 0 Then 'Opdatér tabel End If
Eller endnu bedre logge dato/tidspunkt i en session-variabel:
If Session("Login") <> "" Then If DateDiff("n", Session("Login"), Now) > 3 Then 'Opdater tabel Session("Login") = Now End If Else Session("Login") = Now End If
OK - det kan vi diskutere længe det her uden at blive enige, men lige præcis det med at lukke browseren, kunne klares ved at kalde onunload, der efterfølgende åbner et vindue, hvor Session.Abandon bliver kaldt, og efterfølgende window.close(), og så er den klaret... ved det andet eksempel vil en bruger blive set som værende offline hvis han sidder og læser en længere tekst fx....
OK - enig - den læste jeg ikke godt nok, men stadig skal hver enkelt side opdateres til at have det pågældende check - det være sig så enten som hardcodet i filen, eller ved en include, men stadig skal alle sider opdateres, og der kommer stadig flere database opdateringer, hvis en bruger befinder sig længere tid på sitet...
ok... og hvis brugeren har slået cookies fra kan der ikke benyttes en sessions variabel etc, etc.... der er altid en masse ting man kan komme ud i af fejl etc, og ærlig taget, så ønsker jeg ikke at komme ind på endnu en af de diskutioner igen, så derfor stopper jeg også denne teoretiske diskution for mit vedkommende, for det i princippet ikke har noget med spørgsmålet at gøre.
Spørgsmålet er blevet besvaret af os begge med hver vores holdning, og sådan er det. Det eneste der er efterfølgende er jo at finde ud af hvilken løsning martins ønsker at benytte - alt andet kan jo i princippet for fuldstøndig underordnet, da det blot handler om at vi på det teoretiske ikke kan blive enige....
Ang. den med at sidde og læse på siden i længere tid. Den er svær, uanset hvilken metode man vælger. For det er jo umuligt at konstatere, om brugeren faktisk kigger på siden eller er i bad. Og det problem er stadig eksisterende ved brug af session on_end, da denne jo også bliver kaldt efter X antal min. Og sætter du timeout-værdien ned (som du er inde på) har jeg svært ved at se budskabet med din påpegning. Det kan du i begge tilfælde let løses med en selvopdaterende iframe.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.