16. juli 2005 - 15:34Der er
204 kommentarer og 1 løsning
Opdater database når browser vindue lukkes
Hejsa.
Lidt detaljer:
Koder i ASP VBScript med en tilhørende Access Database.
Jeg har et login system hvor databasen bliver opdateret til at personen er online når han logger ind. Og databasen bliver igen opdateret når han logger af til at være offline.
Mit problem er så følgende:
Hvis brugeren ikke logger af, men bare lukker browser vinduet bliver han logget af ja, men databasen bliver ikke opdateret til at han er offline. Dvs selvom han ikke er online mere står det stadigvæk i hans profil at han er online.
Hvordan kan jeg komme udenom det? Hvordan kan jeg få opdateret databasen til han er offline hvis brugeren kun lukker browser vinduet men ikke bruger knappen "log af"
Danmark vil mindske afhængigheden af globale techgiganter, men det kræver mere end politiske formuleringer og strategier, understreger PROSA’s formand Niels Bertelsen.
Man kan sikkert godt strikke en løsning sammen med noget javascript o.l. men tror ikke at det vil blive særligt kønt :o)
Prøv at søg lidt information ang. global.asa. Det er en fil som du placere i dit webbibliotek. Der er nogle metoder tilgængelige her, bl.a. en der hedder noget med OnSession_End... Ved ikke hvor godt den virker, men så vidt jeg husker vil webserveren kalde denne metode lige inden at sessionen timer ud, typisk 20min, så mon ikke du kan placere noget kode her som kan opdatere dit DB.
En anden løsning ville være at lave et array der har application-scope og lade den håndtere hvilke brugere der er online. Når så en session bliver nedlagt skal du ind og fjerne den fra listen, ved ikke om den løsning ville være nemmere.
Note: We cannot use the ASP script delimiters (<% and %>) to insert scripts in the Global.asa file, we will have to put the subroutines inside the HTML <script> tag.
Og jeg kan jo heller ikke lave en sql hvor WHERE MemberID="&session("bruger") hvor session("bruger")indeholder brugerens unikke ID eftersom sessionen jo er afsluttet..
Så hvordan kan jeg opdatere databasen når jeg ikke kan bruge session("bruger") eller <% %> ???
Kan du ikke lave noget i stil med dette (Skal lige siges at jeg ikke er så stiv i VbScript længere :O))
# Global.asa #
Sub Application_OnStart Dim arrVisitors ' lav et array til holde på de besøgende der er på siden End Sub
Sub Session_OnEnd Application.Lock RemoveVisitor Application.Unlock End Sub
Sub RemoveVisitor strName = Session("name") 'lav en løkke der løber dit array igennem 'hvis der bliver fundet en forekomst af 'strName så skal den fjernes End Sub
Når en bruger bliver logget på systemet kalder du så det array der har application-scope, arrVisitors, og tilføjer det nye navn der i.
Virker godt nok ikke men kender ikke til global.asa Det er første gang jeg prøver det. Men man skal vel linke eller oprette forbindelse til global.asa fra sin asp side?
Nej, man skal ikke linke dertil, det er bare en fil webserveren bruger i baggrunden. Jeg ved ikke om du kan oprette objekter som du gør det der udenfor en metode, det tror jeg ikke. Prøv evt. med at putte det hele ind i et metode
Nej den dur heller ikke desværre :( Men er det ikke fordi at sessionen allerede er slut og Session("bruger") indeholder ikke nogen værdi? (altså brugerens unikke id)
Jo det er derfor.. Session_OnEnd - sessionen er slut og derfor virker sqloffline ="Update Members SET Online=2 WHERE MemberID="&Session("bruger") conn.execute(sqloffline) ikke da Session("bruger")ikke længere indeholder en værdi.
Men kan man ikke få Session_OnEnd til at execute 1 minut før sessionen slutter?
Tror jeg ikke er muligt at gøre, jeg kender ihvertfald ikke til det.
En anden løsning ville være ud for hver bruger i databasen at have et felt som indeholder et tidsstempel. Hver gang en bruger kommer forbi en side bliver dette felt opdateret med Now() værdien.
Når du generer din list skal du så se på hvilke brugere der har været aktive de sidste 30 min, altså hvor forskellen på sidst set og Now() er 30min.
Det kan nok ikke lade sige gøre at bruge en cookie da brugeren ikke længer er på din side, enten har de lukket browser vinduet eller er surfet til en anden side, så jeg tvivler på at man får lov til at hente noget den vej igennem.
kan godt se hvad du mener mht aktiv sidste 30 min.. Men der må squ være en lettere løsning.
Jamen kan man ikke bare hente cookien før session_OnEnd træder i kraft? Og på en eller anden måde sende det id over i global.asa og request.querystring("id") eller noget i global.asa ?
En cookie er blot en lille tekstfil der ligger på den klient som tilgår websiden. Det er rent faktisk det samme der sker med dit session objekt, det er også blot en cookie i bund og grund, altså en tekstfil.
Du skal tænke på at en server i bund og grund er temmelig dum! Det eneste den kan klare er at modtage en forespørgesel fra klienten behandle denne og så retunere et svar tilbage, det er den til gengæld også god til. Dette mønster kan ikke lade sig gøre den anden vej om, hvor det er serveren som tager initiativet til at spørge klienten om noget information, i dette tilfælde en cookie.
Jeg er ikke sikker, men jeg mener at evt. cookies der hører til en side bliver sendt med HTTP headeren når der bliver foretaget et request til serveren. Det er så på den måde at serveren har adgang til cookies.
Hmm følger lige med hvis I finder en løsning Emnet har været oppe utal af gange uden at finde en løsning nemlig..desværre :o( Bla virker server.mappath heller ikke i global.asa Eneste mulige løsning jeg kan se, skal være at fange en onunload, eller onbeforeunload i javascript og så give besked om at opdatere databasen, men har ikke set det udført i praksis endnu
Jeg har lavet mit site sådan at når en bruger logger ind bliver der lagt en cookie på hans maskine. Og der bliver den, også efter han logger af manuelt.
I den cookie skrivers også brugerens unikke id. Og man kan sagtens hente Brugerens unikke id med request.cookies ("autologin")("MemberID")
Men du har ret.. Man kan selvfølgelig ikke hente info fra brugerens cookie hvis han/hun ikke længere er på sitet.. Hmm ved ikke lige hvad jeg tænkte der hehe :)
Men det kan lade sig gøre.. Har set det på mange forskellige websites :) Men ved bare ikke om de bruger global.asa eller hvad de bruger. Ville helst heller ikke ud i det men er desværre blevet tvunget ud i det på den måde jeg har bygget websitet på...
Men ja jeg tror du har ret, det er nok noget javascript jeg skal have fat i.
Kan du måske uddybe det? Eventulet poste et script hvis du har?
Jeg er i fuld gang med at google efter det. Og har da også fundet noget. Den der når du prøver at lukke browser vinduet kommer der en alert og spørger om man er sikker på at man vil navigere væk fra siden.
Vil prøve om jeg ikke kan integrere en sql i den :)
aerobee >> ja, men der dukker problemer op vil du sikkert se. For eventen kører idet der lukkes for vinduet. Jeg mener at have prøvet engang at submitte en form til en side som skulle opdatere databasen, men problemet var så at vinduet når at lukke inden det kommer dertil. I IE findes der en unbeforeunload kommando, men den dur så kun i IE,,,såå
så vidt jeg husker kan du ikke åbne vinduer sådan af sikkerhedsmæssige årsager Forestil dig scenariet, du lukker et vindue, men der åbnes et, du lukker det, men der åbnes et igen ,osv osv ;o) Men prøv ad, Er spændt på om det lykkeds dig :o) -- Dog er der lige en mente Alle som ikke har aktiveret javascript vil ikke blive opdateret i din database Dem kan du så prøve fange i din global.asa Men der skal du så undgå at dem du har fanget bliver fanget igen hmm må vist også google lidt ;O)
Haha.. Det sidste du skrev kunne lyde som en spiritus prøve ;O)
Men du misforstår.. Når du lukker browser vinduet kommer der en popup ja, men den skal kun bruges til at køre sql sætningen.. Dvs den bliver kun vist i max 1 sekund derefter bliver popupen lukket automatisk..
Blot en tanke, men prøv at gå ind på dating.dk, lad siden loade helt, og derefter bare luk den igen.. Der kommer en "quick" popup..
jeg får hverken den popup i IE eller FF Du må tænke på en del mennesker efterhånden bruger popup spærrere som sikkert spærrer for den slags popup, for netop undgå scenariet med at man ikke kan komme væk fra en side
popupen skulle gerne komme i nederst højre hjørne.. Den er ikke ret stor, en 50x50px vil jeg tro. (og den er hurtigt væk igen) Jeg bruger også popup blocker men jeg får den stadig i IE
yes den overså jeg ;o) Hvis du kigger i kilden vil du se at de netop benytter onBeforeUnload , som er en IE ting - derfor får du ikke pouppen i FF og andre mozilla browsere
jeg fik en tanke, som nok afhænger af hvor mange brugere man har online på en gang Men man kunne jo registrere hver gang en bruger bevæger sig på sitet i en tabel med brugernavn og tidspunkt I ens application kunne man så i et givet tidsinterval så tjekke hvem som har bevæget sig og hvem som ikke har og derved opdatere sin online bruger tabel Problemet er hvis man har rigtig mange online samtidig så vil det belaste serveren en del med så mange database opslag
Kunne man så ikke lægge en begrænsning ind. F.eks. have en session variabel der bliver talt op hvergang man ser på en ny side, og når den når et defineret antal, så skriver den i databasen og nulstiller herefter sig selv.
Hvis man sagde at brugeren skulle have 8 sidevisninger før den blev nulstillet ville det jo reducere det væsentligt.
Ikke nogen optimal løsning men vil det mon kunne bruges?
Jeg har ikke lige læst alle de svar der er kommet, men hvorfor gør du det ikke på den måde, at hvis brugeren ikke har loaded en side i f.eks. 20 min, så blir han sat til offline?
Altså, hvis hans seneste opdatering er kl 20:05 og kl nu er 20:50 så blir han ikke regnet som online.
Da listen kun vil kigge på dem som har været aktive inden for 20 min f.eks.
Du kan jo så altid lave en kode, som sætter alle brugere som ikke har loaded en side inden for de sidste 20 min.
morten-hbm >> Fordi det ville kræve at hver gang en bruger går ind på en side så skulle tidpunktet registreres i en tabel, og eftersom der er rigtig mange brugere og rigtig mange side opslag, ja så vil det belaste serveren en del
Dette ville du kunne se hvis du havde læst nogle af kommentarene istedet for at smide et svar som ikke kan bruges ;o) Står fx i de tre kommentarer lige oven over dit indlæg :o)
jeg tror de fleste indfinder sig med at der går 20 min eller lignende før en session timer ud Jeg synes i al fald at jeg oplever på de fleste sider at folk man tror er online ikke reagerer og lidt efter står de som offline - hvilket kunne indikere at det er sådan det foregår Problemet i asp er så at man ikke altid kan stole på at session_onend kaldes når en session timer ud, kun når en session bliver abandon Det er ikke noget jeg selv har forstand på! andet end erfaringen viser det og flere herinde skriver at den ikke er til at stole på
Om det så evt fungerer anderledes i et sprog som php, det er da muligt, men det aner jeg heller ikke :o/
Men selvom jeg brugte sessin_OnEnd ville det stadig ikke kunne lade sig gøre..
Dette skyldes at session_OnEnd først bliver kaldet når sessionen er slut, dvs så har jeg ikke længere brugerns unikke id og kan derfor ikke opdateret tabellen til at han/hun er offline
hmm ok - det må vist være endnu et tegn på at session_onend ikke altid virker efter hensigten, for meningen er jo ellers at man kan nå at lave noget "lige inden" sessionen slutter
Ok. Men ifølge mine tests kan jeg kke få det til at virke..
Problemet med global.asa er jo at man ikke kan skrive asp derinde. Derfor, for at fange brugeres id skal jeg bruge Session("Bruger") som jeg har kaldt den.
id = session("bruger") sqloffline ="Update Members SET Online=2 WHERE MemberID="&id conn.execute(sqloffline)
Men det kan jeg ikke få til at virke... Det ser ud som om at "id" er tomt når sql bliver execute´et
hvad mener du med at man ikke kan bruge asp? Det er jo i princippet klart, for det er en .asa fil og ikke en .asp fil ;o) Men hvis du koder i vbscript normalt i dine asp filer så ligner global.asa en normal asp fil i og med den også kodes i vbscript
nej sådan dur det ikke, alt du har i din global.asa skal være i sub rutiner Og det eneste som køres er det som er givet i session_onend, eller session_onstart eller tilsvarende for application Har du prøvet: --- <script language="vbscript" runat="server">
Så prøv benytte den fulde sti til databasen, og så i Session_OnStart kan du sætte session.timeout til fx 2 så sessionen hurtigt dør, så er det lidt nemmere at teste på når du ikke skal vente 30 min hver gang :o)
Jeg tester det ved at lukke browseren.. Derved ende sessionen jo også...
Problemet med at opdatere db når session udløber mens brugeren er på siden er nem og løse.. Problemt er den når brugeren lukker browseren uden at logge af
nej det er jo lige netop der du så har misforstået pointen :o) Når du lukker browseren så lukker du browseren og det er det Der er ingen som fortæller din server at du har lukket forbindelsen! Derfor går der 30min før session_onend bliver kørt Det ville du kunne se hvis du tager et af de utallige eksempler på nettet som blot tæller hvor mange som er online Hver gang man åbner en browser tælles der en op, hver gang man lukker en tælles der først en ned efter 30 min
aha... Jamen, hmmm... Hvordan kan jeg så få opdateret min database til brugeren er offline hvis han lukker browseren? Derved slutter sessionen jo, og kan derfor slet ikke fange noget id overhovedet i global.asa til at opdatere ham til offline...
nej sessionen slutter ikke når browseren lukker Sessionen slutter efter den tid session.timeout er sat til Problemet med session_onend er så at den ikke er stabil, dvs den køres tilsyneladende ikke konsekvent jeg vil foreslå dig at prøve den her, hvor du lige skal rette din sti til databasen Når session.timeout er sat til 2min så må du kunne se i din database rimelig hurtigt om der sker noget
Jeg ser desværre snart kun en trist udvej.. Og det er at bruge OnBeforeUnLoad. Så bliver alle der bruger IE da opdateret når browseren lukkes eller de forlader siden uden at logge af, og dem der ikke bruger IE, ja, så må de jo lide under det... Nej, det dur bare ikke, for så vil aller der bruger andet end IE jo stå som online indtil de logger ind og logger ordentlig af. Dvs en bruger kan stå som online (selvom han ikke er det) i flere uger (hvis han er på ferie) hvis han bare har lukket browseren.. Nej det dur heller ikke.. *suk* Jeg må blive ved med at prøve, og lede...
ideen med session_onend er som sagt at den køres _lige inden_ sessionen slettes Derfor bør dit brugerID også være til stede Men megen debat herinde har gået på man ikke 100% kan stole på at den rent faktisk køres Samt problemet med at der går de standart 20-30 min før den køres
Er i sikker på at det er muligt at benytte sig af session objektet i session_OnENd rutinen? Et session objekt er vel ikke andet end en cookie der også ligger på klienten og som bliver sendt med hver forespørgsel, så det vil være omsonst at forsøge at tilgå dette objekt.
Fundet på w3schools.com: ASP solves this problem by creating a unique cookie for each user. The cookie is sent to the client and it contains information that identifies the user. This interface is called the Session object.
Har siddet og læst nogle andre forums ang. om session_onend bliver kaldt, og det som jeg forstod var at den vil blive kaldt med mindre at serveren mister strømmen eller på anden måde bliver afbrudt.
soes >> ja. Cookien bruges til at identificere en given klient og sammenholde denne med en given session på serveren Når session_onend køres, så har serveren ingen forbindelse til klienten, korrekt! Men serveren har stadig alt indholdet af sessionen, for det gemmes nemlig ikke i en cookie, kun sessionens unikke id gemmes der Så når sessionen dør, så ved serveren at den skal slette session("brugerId") for en given session den ikke længere har forbindelse til Men inden den sletter dette id kan man tilgå det
soes >> Application_onend bliver muligvis kaldt ved strøm brud, men der er forskel på application og session. Du kan gå ind i dine cookies og se hvilke informationer der bliver gemt i din sessions cookie , du vil se at kun sessionens id er gemt
Lige nu har jeg en cookie fra eksperten som er min sessions cookie, den indeholder oplysningen om hvem jeg er (a0f9e17fe879eea647084beba909a87b) Denne cookie bruges så serveren ved lige præcis hvem jeg er Når jeg skriver et indlæg her, så er der noget kode bagved som gør at mit navn kommer til at stå ude til venstre. Dette er sikkert gemt i Session("Navn") Men hvilken session("Navn") ? jo den session som har id a0f9e17fe879eea647084beba909a87b som er angivet i min cookie Når jeg slukker min browser og lukker min computer og går ud af døren. Så findes min cookie ikke mere, men jeg fortæller ikke serveren at den ikke findes mere Serveren tror jeg sidder og keder mig, den ved kun at jeg ikke surfer videre på andre sider Hvis session.timeout er sat til 20 min så sker der det at den efter 20 min siger, nej nu har han sku været for stille for længe, det koster mig ram at sidde og gemme på hans session når han ikke laver noget Derfor kalder serveren Session_OnEnd og dernæst sletter den alt relateret til den givne sessions id Og derfor er det også meningen at man kan få fat i sessionen og lave statestik på den eller andet inden den slettes --- bedre kan jeg vist ikke forklare det
busschou >> Hvis IIS kun holder information om session og application state i hukommelsen og ikke på noget persistent media så vil den jo ikke have nogen mulighed for at afbryde de forskellige sessions og lukke applikationerne ned når den kommer online igen efter f.eks. et strømsvigt
soes >> Meningen med apllication_onstart er at den køres når serveren starter, eller hvis du uploader en ny global.asa Application_onend køres tilsvarende før serveren lukker ned Men det er klart at ved et strømbrud så kan den ikke køre den, i og med den kører på strøm ;o)
aerobee >> hvis du finder en løsning på problemet som virker hver gang, så glæder jeg mig til at se den :o) For det er ikke sket før herinde, kun folk som opgiver er vist sket :o/
Har ingen planer om at opgive.. For hvis jeg gør det vil mine brugere stå som online når de er offline hvis de ikke logger af rigtigt. Og det vil de bliver sure over, og i værste fald lade være med at besøg siden igen..
aerobee >> kan du ikke lige prøve at afvikle dette script, bare for at se om vi kan hente nogle oplysninger ud når sessionen bliver afsluttet.
' glabal.asa
Sub Session_OnStart session.timeout = 2 End Sub
Sub Session_OnEnd log() End Sub
Sub log() Dim fso, txtfile Set fso = CreateObject("Scripting.FileSystemObject") Set txtfile = fso.CreateTextFile("C:\Inetpub\wwwroot\ondate.dk\db\session.info", True) txtfile.Write("UID: " & session("bruger")) txtfile.WriteLine(" - SessionID: " & Session.SessionID) txtfile.Close End Sub
Du kan jo gøre det at du i session_onend lægger sessions ideet over i en variable som du har gemt i applicationen Så kan du lave en side hvor du skriver den variable ud noget ala --- sub application_onstart application("start") = "ID-LISTE " application("slut") = "ID-LISTE " end sub
sub session_onstart session.timeout = 1 Application.lock Application("start") = "application("start") & "," &Session.SessionID Application.unlock end sub
sub session_onend Application.lock Application("slut") = "application("slut") & "," &Session.SessionID Application.unlock end sub --- Du kan så lave en normal asp side hvor du kan skrive de variable ud som response.write application("start")&"<br>"&application("slut")
soes >> session_onend kaldes altid når session_abandon kaldes, problemet (så vidt jeg har læst herinde et hav af gange) er at session_onend ikke altid kaldes når sessionen bare timer ud
nå men anyways, nu kører vi jo hårdt aerobee og synes ikke der er nogen grund til at lave dobbelt arbejde Eller sagt på en anden måde Synes ikke der er nogen grund til at vi simultant beder aerobee om at gøre forskellige ting Så jeg holder mig bare i baggrunden
ok du prøvede ikke mit eksempel så? Det her det virker hos mig, og det viser flere ting 1) Det viser at sessionen timer ud et minut efter man har lukket browseren fordi session.timeout er sat til 1 2) Det viser man kan tilgå sessions objecter i session_onend --- global.asa --- <SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart Application("start") = "ID-LISTE " Application("slut") = "ID-LISTE " Application("antal") = 0 End Sub
Sub Session_OnStart session.timeout = 1 session("antal") = Application("antal") + 1 Application.lock Application("antal") = Application("antal") + 1 Application("start") = Application("start") & "," &Session.SessionID Application.unlock End Sub
Sub Session_OnEnd Application.lock Application("slut") = Application("slut") & "," &Session.SessionID Application.unlock End Sub
response.write "så mange har her været i alt nu: "&application("antal")&"<br>" response.write "id´er til start: "&application("start")&"<br>" response.write "id´er til slut: "&application("slut")&"<br>"
%> --- gem dem på din server i roden, det har du forhåbentlig gjort med global.asa i forvejen for den virker _kun_ fra roden :o) Åben din browser og gå til test.asp, åben flere, luk nogen..tryk f5 og se listen ændrer sig efterhånden som sessionerne dør et minut efter browseren er lukket
og så er vi tilbage hvor man måske kan sige at en løsning for dig kunne være at gemme de online brugere i Application("Online") og så i Session_OnEnd fjerne dem når sessionen dør
Nej så ikke de forslag før nu, sorry... Kan du give mig et eksempel på hvordan jeg gemmer min brugere i Application("Online") og hvordan jeg så viser på min side hvormange der er online?
hvis du kun vil vide hvor mange der er online og ikke hvem, så er det nemt nok. sådan her <SCRIPT LANGUAGE=VBScript RUNAT=Server>
Sub Application_OnStart Application("intBrugereOnline") = 0 End Sub
Sub Application_OnEnd End Sub
Sub Session_OnStart Application.Lock Application("intBrugereOnline") = Application("intBrugereOnline") + 1 Application.Unlock End Sub
Sub Session_OnEnd Application.Lock Application("intBrugereOnline") = Application("intBrugereOnline") - 1 Application.Unlock End Sub
</SCRIPT> --- Hvis du ønsker at hive et navn eller id eller noget ud af en database og gemme det i et array ja så gør du det Der er intet spooky i det om der står application, eller session, eller cookie skal du ikke lade dig skræmme af Det er kun et spørsmål om hvem der har adgang til at se variablen Det du gemmer i Application kan alle brugere se hvis du hiver det ud på en side ligesom i eksemplet :o) Så du kan når en bruger logger ind opdatere dit array eller din streng eller hvad du nu vil gemme i Application("Online") Den kan du opdatere fra din login.asp side!, du behøves i princippet kun at definere den i global.asa Du skal blot huske at låse og åbne applicationen før evt opdateringer I session_onend skal du så kode din kode når der skal fjernes en bruger fra listen/arrayet -- Du slipper for at have databaseforbindelser i din global.asa ved denne metode I din application_onstart definerer du dit array eller lignende I session_onstart definerer du din timeout, men ikke noget specielt andet I din login.asp opretter du database forbindelse og opdaterer din application("Online") samt sætter en session("BrugerID") I din session_onend fjerner du brugeren fra application("Online") ved at bruge din session("BrugerID") som reference
Så det kommer lidt an på hvor mange brugere du har online samtidig, samt hvad du vil bruge som reference for at det går hurtigst muligt Du kunne også benytte dig af et scripting.dictionary i stedet for et array. Så kan du benytte brugerid som nøgle Du spørger så blot til om nøglen med brugerid´et er true eller false, svarende til online eller offline og hvis ikke den eksisterer så opretter du den Det er nok det nemmeste for så slipper du for at løbe et array igennem Du kan læse lidt om scripting.dictionary her http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/jsobjdictionary.asp
Men jeg skal også være sådan at man kan vise hvilke brugere der er online. Og man skal kunne søge på om en enkelt bruger er online eller ej, ydermere skal der også stå på brugerens profil on han er online eller offline..
Så bliver det indviklet.. Derfor jeg startede med at bruge en db til det.
Du kan jo prøve ud fra mit eksempel 12:29:04 og tilføje database adgang og se om det virker -- Det er muligt med dictionary og nok ikke mere bøvlet end database, plus hurtigere end en database da man slipper for at opkalde databasen Et dictionary er som en slags dynamisk array Det består af en række indgange/nøgler og en tilsvarende række værdier for de nøgler Hvis du overalt lader enten brugerid eller brugernavn gå igennem så kan du gøre sådan her (hvis du vælger id) I dit dictionary er nøglerne brugerenes id På din oversigt over online brugere, der løber du blot hele dit dictionary igennem og viser alle de nøgler hvis tilsvarende værdi er True Når man søger på et Id så slår du bare op på det id og ser om det er True eller False Når du går ind på brugerens profil så har du sikkert i forvejen brugerens id, igen slår du blot op og ser om der står True eller False -- Men klart hvis man ikke har brugt dictionary før, så virker det måske bøvlet Jeg vil mene det er en fordel frem for database til det formål, i og med du sparer opslag i databasen, og du sparer spildplads i databasen da du ikke benytter det til noget andet MEn prøv endelig med database først :o)
hehe ja måske lidt energi deroppe hjælper ;o) Ja prøv ad Prøvede du mit forslag 12:29:04? Bare for at se om det basale fungerer som forventet :o) Du kan bygge databasen ind i dens session_onend Så kan du jo i alt fald se at når Application("slut") er opdateret så bør databasen også være det :o)
du prøver at tilfølje det her igen til session_onend -- Set Conn = Server.CreateObject("ADODB.Connection") strDSN = "DRIVER={Microsoft Access Driver (*.mdb)}; " &_ "DBQ=" & "C:\Inetpub\wwwroot\ondate.dk\db\ondate.mdb" & "; password=" Conn.Open strDSN
sqloffline ="Update Members SET Online=2 WHERE MemberID="&brugerID conn.execute(sqloffline)
hvor brugerID selvfølgelig er session(bruger) De steder hvor jeg har skrevet Session.SessionID kan du evt rette til Session("bruger") For at sikre at den har fat i brugerid´et også
Men den her: Jeg er session nr: 302067994 Matcher jo ikke brugerens MemberID i min database.. Dvs jeg kan ikke sige, det er memberID 75 der skal sættes som offline..
og der var en smutter sqloffline ="Update Members SET Online=2 WHERE MemberID="&brugerID skal være sqloffline ="Update Members SET Online=2 WHERE MemberID="&session("bruger")
citat "1) Det viser at sessionen timer ud et minut efter man har lukket browseren fordi session.timeout er sat til 1"
Men session timer jo også ud efter 1 minut af inaktivitet.. Dvs, hvis jeg sætter session.timeout = 30 så vil session først luk 30 min efter jeg har lukket browseren? Dvs at brugeren stadig står som online i 30 minutter efter han har lukket browseren? Er det forstået korrekt ?
Her er en yderligere ting som jeg ikke helt forstår:
Sub Application_OnStart Application("start") = "ID-LISTE " Application("slut") = "ID-LISTE " Application("antal") = 0 End Sub
Den er bare fin ja :) Men... Vedkommenes session kan og skal jo ikke stå som online med det samme han går ind på websitet... Brugeren bliver først tildelt hans/hendes ID når han/hun logger ind (tildelt session("bruger")) Dog er der også et autologin system hvor brugeren bliver tildelt hans/hendes ID med det samme og bliver redirectert til member siden..
Så der virker Application_OnStart da ikke for godt eller ?
ok må hellere forklare mig Jeg gav et eksempel for at se om man kunne regne med at man kunne læse ens sessions i session_onend og for at se om session_onend blev kaldt med det samme eller når den timede ud Derfor lavede jeg det eksempel Nu ville du have database med Det virkede ikke for dig før Derfor foreslog jeg dig at putte det ind i mit eksempel så du kunne se om det måske bare er fordi man ikke kan connecte til databasen at der ikke sker noget Med andre ord så kan du ikke bruge det eksempel jeg gav dig til en skid andet end til test Der er ingen grund til at tro at du kan få det hele til at virke på een gang Tag det med ro og tag et skridt ad gangen, ellers er det ikke til at overskue Hvis det var det ville der ikke være 90 indlæg i denne tråd nu vel ;o) Så tag og sæt databasen på min test Når du så på siden kan se at sessionen er død, så burde du også kunne se det i databasen Hvis du ikke kan det så er der jo ingen grund til at lave den store forkromede løsning og bruge tid på det, når den så heller ikke vil virke..vel ? ;o)
Godt så Application_OnStart >> Køres når serveren starter eller du uploader en ny global.asa Application_OnEnd >> Køres når der lukkes ned for serveren Session_OnStart >> Køres når sessionen starter Session_OnEnd >> Køres når sessionen timer ud eller ved kald til session.abandon -- godt så ydermere -- Så snart du går ind på en side som ender med .asp så registerer din server en ny session! Så hvis din login side hedder login.asp så er sessionen startet inden man taster sit brugernavn, Men det er jo også logisk nok hvis du læste min kommentar med hensyn til den cookie der For når du så siger session("navn") = request.form("navn") Så skal serveren allerede der vide hvilken session("navn") den skal sætte lig med "IB" så den ikke kommer til at overskrive "Åges" session Så du må forstå at selvom du aldrig nogen sinde skriver noget om session på dine asp sider Så oprettes der en unik session så snart en person går ind på en asp side
Men mit spøgsmål rettede sig mod.. Hvordan fanger global.asa Brugerens unikke ID som senere skal bruges til at opdatere databasen? Er det via den her:
<% brugerID = Session("bruger") Session("bruger") = brugerID acs = Session("adgang") Session("adgang") = acs 'Session.Timeout = 30 if not acs then printbox = 1 end if
global.asa fanger den her --- sqloffline ="Update Members SET Online=2 WHERE MemberID="&session("bruger") --- For når du en gang har sat session("bruger") på en side så er den tilgængelig på samtlige sider så længe sessionen lever
Men hvorfor laver du dobbelt konfekt? Du skriver jo egentlig a = b b = a c = d d = c --- der er ingen grund til at gemme sessionen i en variable og så med det samme gemme den variable i sessionen, for så er sessionen jo lig det den var lig med et splitsekund før :o/ ?
du kan spørge på en session som på en variabel Om du skriver --- Session("adgang") = acs if not acs then --- eller --- if not Session("adgang") then --- ja det giver samme resultat
Well, det ser ud til at det med at opdatere min db via session_OnEnd ikke virker. For når jeg kan se at sessionen er død, og jeg får et nyt id så bliver db ikke opdateret...
Det er jo ikke kun dem som lider under det Alle dem som kigger i profilerne og tror de er online bliver jo "fuppet" Men du kan jo spørge dem ad på de store sider hvordan de gør
Hey hov... Loggede ind med min admin profil som har id nummer 75.. Derefter gik jeg til siden der printede hvilket besøøgs nummer man har osv, den der test.asp som du lavede busschou.. Stod fast der i et par minutter fordi jeg lige skulle have noget at drikke, så reloadede jeg siden og dette kom frem
Jeg er session nr: 302068000 mit personlige besøgsnr er: 3 så mange har her været i alt nu: 3 id´er til start: ID-LISTE ,,, id´er til slut: ID-LISTE ,75 <---- 75, mit rigitge MemberID :)
Kan jeg ikke teste på en eller anden måde om global.asa på noget måde connecter til min db.. Eller teste om det er den korrekte sti.. Whatever, teste et ellen andet.. For hvis det virker med korrekt id når sessionen afsluttes så må db da også kunne opdateres
se mit dilemma er at jeg ikke er noget videre inde i hvordan det virker på ens egen computer frem for på nettet Jeg tester altid selv direkte over nettet
Jeg kan bare ikke forstå hvorfor man ikke kan opdatere db fra global.asa Men kan man så ikke sætte den til at redirecte til en anden side som er en .asp hvor sql så køres ?
Du kunne jo lave en asp side som opdaterer databasen som du ønsker og teste at det virker, at der ikke er overset noget Og så sætte den ind i global.asa bagefter
redirecte hvornår? Du kan "ingen ting" i global asa Du har ikke fat i en klient, ergo er der intet sted at redirecte hen Du skal forestille dig at du er på serveren Med mindre du nu igen snakker om det der unload
Den opdatering laver jeg jo når brugeren bruger log af knappen.. sql er helt identisk...
Det der er anderledes er at jeg normalt bruger mappath i min connection string.. og det gør jeg ikke i global.asa--tror det måske er der, der går noget galt.. Men ved det ikke...
ok så lav en normal asp side hvor du udskriver din server.mappath Server.mappath giver jo en hel sti Så hvis du udskriver den må du kunne se om den passer overens med en absolutte sti du har skrevet
hmm bare et forsøg Måske global.asa vil have den som direkte sti Altså hvis den ligger en mappe over, så "../db/db.mdb" hvis du forstår? Bare et forsøg ;o)
interessant måske, men nok mest i anden sammenhæng Det er interessant hvis du ikke gider huske din connectionstring på alle dine sider Så kan du nøjes med at definere den i global.asa Eller hvis du har en anden fil med funktioner du inkluderer kan du også definerer din connection der Men det siger intet om hvorvidt du kan connecte i session_onend
Den der står her http://forums.aspfree.com/t26791/s.html (helt nede i bunden) der får han slettet noget. Men jeg kan ikke finde ud af at omskrive koden så den passer til min db. Er ikke inde i global.asa
Der er ikke noget spooky i det :o) Fra hans session_onend kalder han en sub rutine Det er ganske normalt i asp at have Sub og Function , altså funktioner Så han laver en funktion til at opdatere databasen, og den funktion kalder han så fra session_onend ---- Sub OpdaterDatabase() //connection til database mm End Sub
hvor som helst uden for de andre subs Din global.asa skal altid indeholde de fire "normale" subs som vi har snakket om og derudover så kan den indeholde alverdens andre hjemmelavede subs Det eneste den ikke kan er at indeholde kode udenfor subs Det skyldes jo at man ikke "kører" en global.asa fil. Men man kalder metoderne i den
jeg synes du skal overveje om det er det værd Du vil uanset hvad have en tidsovelap på 20-30 minutter Men læs lidt på dictionary... så kan vi jo tage den derfra en dag hvis det er
Jeg er efterhånden blevet ligeglad med de extra 20-30 minutter.. Nu vil jeg bare have det sådan at db bliver opdateret med at han er offline. Om det så først sker 20 min efter, det er nu ligemeget. Så må man bare skrive til folk på sitet at de skal huske at logge ordentlig af ved at bruge log ud knappen..
Men hvad, jeg kan jo stadig ikke få den til at opdatere databasen efter 20-30 minutter.. Bare jeg kunne det, så var jeg tilfreds for så er det kun de 20-30 min vi snakker om og ikke for evigt (hvis brugeren ikke besøger siden igen)
Må vel lukke mine øjene og håber at alle brugere bruger IE og så bruge onbeforeunload funktionen..
Det vil aldrig blive godt, men havd kan jeg ellers gøre :(
Tusinde tak for hjælpen busschou, du har fortjent pointene..
<script language="javascript"> function ShowTimeoutWarning () { window.alert( "ondate.dk - Information \n \n Du har været inaktiv i 30 minutter og er derfor blevet logget af." ); document.location.href=''; } </script>
Men den vil vel stoppe med at tælle når browser vinduet lukkes. Men virker hvis brugeren stadig er på sitet. Mon ikke man kan lave et script der fortsætter med at tælle selvom browser vinduet lukkes og derefter eksekvere sql´en ? Og som selvfølgelig nulstiller sig selv ved aktivitet, altså page requests.
Jeg erkender hermed at jeg er blevet slået, og kan ikke finde den løsning jeg håbede på. FOR NU!!! (skal nok komme hehe :P)
Så nu vil jeg satse på følgende:
sql = "UPDATE Members (Last_Seen) VALUES ("&"'"&FormatDateTime(Now(), vbShortTime)&"')" set rs = conn.execute(sql)
Ovenstående sql indsætter jeg på samtlige dokumenter.
Okay? Så må jeg jo se hvor langt det kan bære... (hvor mange brugere før det bliver langsomt) INSERT gør jeg når brugeren opretter en profil...
Men her er så et spørgsmål...
Hvordan laver jeg det sådan at systemet kigger tabellen Members feltet Last_Seen igennem og sætter brugeren til offline hvis han/hun ikke har været aktive i 20 minutter (by request page)???
Du har vel en side hvor du normalt ville sige noget ala Select * From Members Where Online = True Nu laver du bare en ala Select * From Members Where Last_Seen < "for 20 min siden" Sagt på en anden måde behøves du ikke have et off/online felt Om du skal tjekke på om en felt er true eller false, eller tjekke om et felt er mere end tyve min gammelt, det er vist et fedt :o)
For %¤##!"# du svarer hurtigt hehe, det er squ dejligt :P
Select * From Members Where Last_Seen < "for 20 min siden" <--- ahh what? haha... Du mener Select * From Members Where Last_Seen < FormatDateTime(Now(), vbShortTime i den stil ikke?
hvis jeg var dig og skulle lave det om så ville jeg droppe det online felt og sætte et dato felt i fuld dato format Så kan du vælge dem sådan her "Select * From Members Where Last_Seen Between "& Now() &" And "& DateAdd("n",-20,Now()) og hvis du skal tælle dem så det samme bare med Count(*)
anyway, det er ikke sikker på jeg er lige hurtig resten af natten ;o) Har vist også et liv...eller noget hehe Men hvis du har lyst så må du da gerne sende en karma hilsen ;o)
sql = "UPDATE Members (Last_Seen) VALUES ("&"'Now()&"' WHERE MemberID="&Session("Bruger"))" set rs = conn.execute(sql)
sqlwoohoo = "Select * From Members Where Last_Seen Between "& Now() &" And "& DateAdd("n",-20,Now()))" set rswoohoo = conn.execute(sqlwoohoo)
Og denne på forsiden:
sqlwoohoo = "Select (COUNT) as Antal From Members Where Last_Seen Between "& Now() &" And "& DateAdd("n",-20,Now()))" set rswoohoo = conn.execute(sqlwoohoo)
Og på brugerens profil skal jeg vel køre noget ala:
sqldamn = "Select * From Members Where Last_Seen Between "& Now() &" And "& DateAdd("n",-20,Now()) WHERE MemberID="&session("bruger"))" set rsdamn = conn.execute(sqldamn)
uha nu er det jo lang tid siden vi snakkede sidst så jeg kan ikke helt huske hvad problemet var men siden da har jeg lavet en artikkel om global.asa http://www.eksperten.dk/artikler/752 Jeg angiver til sidst et eksempel (som virker!) på hvordan man kan sætte brugeren online i session_onstart og offline i session_onend Det er det bedste der kan gøres og dvs der går session_timeout tid før en bruger bliver logget ud, såfremt session_onend køres, hvilket ikke kan garanteres 100% desværre -- Om du skifter til mysql eller mssql eller postgresql eller andet, det er "et fedt" Det er jo kun et spørgsmål om _hvor_ du registrerer oplysningerne og ikke et spørgsmål om _hvordan_ og _hvornår_ du gør det :o) Så problemet er i sidste ende stadig at hvis en bruger lukker browser vinduet, så kan dette ikke registreres med garanti -- Håber det er nok, for jeg orkede ikke lige at læse det hele igennem :o) Ellers skriv endelig igen
Ja, jeg har læst din artikel, og den er meget godt skrevet, fik det dog aldrig til at virke.. Men jeg ved der er andre måde man kan få det til at virke med en mysql db end en access db, ved bare ikke hvordan, og det er jo så der du kommer ind i billedet.. Kender du noget til det ?
øhh ikke andet end at man laver en database forbindelse til sin sql server i stedet for til access Når den er lavet så er syntaksen for at indsætte lidt anderledes For eksempel skal der ikke # omkring datoer i mysql Men databasen har jo intet med at gøre om en bruger logger ud Det har kun noget at gøre med din connection string Så hvis det er fordi du ikke har kunne få din access database til at forbinde i global.asa, så er det da muligt din mysql gør Jeg havde selv bøvl med det i det eksempel jeg lavede Og det viste sig at være fordi den connection string jeg brugte ikke kunne bruges i global.asa, der skal man bruge en ..hmm hedder dns less ...tror jeg.. hehe Anyways, den forbindelse jeg bruger normalt ser sådan her ud ---- Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open "DBQ=d:\\min_sti\mindb.mdb;UID=;PWD=;Driver={Microsoft Access Driver (*.mdb)};" --- Den virker ikke i global.asa men det gør denne --- Set Conn = Server.CreateObject("ADODB.Connection") DNS = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\\min_sti\mindb.mdb" Conn.Open DNS --- jeg kender desværre ikke til strengene til mysql men prøv se her om ikke den gemmer sig et sted her www.connectionstrings.com
Grunden til jeg spørger er fordi jeg ved at mulighederne med en MySQL db er anderledes end en access db. Eksempelvis har jeg set mange forslag på nettet ved at google lidt hvor databasen (MySQL) bliver opdateret når en session udløber og alle påstår de virker. Har prøvet og kæmper stadig lidt med det. Men det er nogle helt andre løsninger end jeg har set med access. Jeg er meget mere hjemme i MySQL end i access så jeg vil da prøve om jeg ikke kan få skidtet til at virke.
jeg kan bare ikke se hvad de to ting har med hinanden at gøre det er det samme som at sige at det er nemmere at registrere når vinduet bliver lukket ved at en bruger trykker alt-f4 i php end i asp begge sprog kører på serveren og kan ikke registrere hvad klienten gør --- Her er det det samme Mysql har intet med asp at gøre, access har intet med asp at gøre Mysql kører på en server for sig og har intet med ens sessioner på asp serveren at gøre Hvis du skal registrere at en session dør så gør du det i asp, php, asp.net eller hvad man nu benytter :o) Så jeg kan ikke se det skulle gøre din registrering nemmere eller mere sikker Det er bare en anden database Du kunne også vælge at gemme oplysningerne i en txt fil, det er så bare endnu en måde at gemme det på. Men en txt fil kan ikke selv finde ud af om en session dør ;o) -- Anyway hvis du får det til at virke må du da endelig skrive
Ja så må jeg jo bukke under og indrømme at det ikke er nogen forandring i at bruge en MySQL db end en Access db. Har nu besluttet mig for at køre det hele i sessions.
Altså: Når brugeren logger ind opretter jeg følgende session: Session("bruger") hvor den tildeles det id brugeren har i min db. Derefter oprettet jeg Session("online") som tildeles værdien true ved login.
Men hvordan gør jeg så følgende? Brugeren logger ind, får tildelt sit id i session("bruger"), brugeren skal så sættes som online i min online liste ud fra session("online") og når han/hun logger af skal hans/hendes session slettes vha session.abandon() og brugeren skal fjernes fra online listen. Ydermere, hvis brugeren ikke logger ud men blot lukker browseren skal man vente på session.timeout = 20, hvilket også er ok, men hvordan bliver brugeren så fjernet fra online listen ved session.timeout? Måske ved at gøre sådan her?
online = Session("online") <-- som tildeles ved login med værdien true
Brugeren er <%if online then%>online<%else%>offline<%end if%>
Men men men... Hvordan ved serveren at når en bruger finder frem til en eller andens profil at det er brugeren med f.eks id 75 som ikke har en session mere og skal derfor sæte ham/hende til offline i profilen? Jeg kan ikke overskue det, og har prøvet meget. Det eneste jeg vil bruge min db til nu er følgende: Tildele brugeren der logger ind hans/hendes unikke id fra databasen, for at man kan finde yderligere oplysninger om brugeren.
Giver noget af det her mening?
Jeg fortsætter spørgsmålet herinde pga det stadig er det samme emne det drejer sig om og det ikke er blevet løst. Mener at du, busschou, må være manden til det. :) Sætter yderligere 60 points på spil og de vil blive tildelt ved en oprettelse af nyt spørgsmål.
hej aerobee , jeg har været ude og kommet sent hjem, så nu kalder sengen :o) Men jeg kigger lige på det first thing in the morning ;o) Det er ikke umuligt det du der skitsere, så jeg laver et lille eksempel i morgen formiddag, for lige nu er jeg monster træt :o)
godmorgen friske igen ;o) Stiller lige dine krav op som jeg ser dem 1) Ved login set session("bruger") = rs("id") jvf login og Session("online") = True Dette er muligt :o) Løsning: kan laves i global.asa 2) Oprette en liste af online brugere udfra deres session Dette er ikke muligt :o( Årsag: Sessionen er unik for hver bruger og ikke tilgængelig for andre brugere Løsning: Når brugeren logger ind sættes et felt i databasen rs("online") = True 3) Logge brugere ud ved session.abandon og hvis de lukker browseren Dette er muligt såfremt du jvnf 2) gør det med en database Løsning: Da session_onend køres både ved kald til session.abandon og når sessionen timer ud Så kan dette lettets gøres i global.asa ----- Du skriver selv at du har tænkt en del over det med online listen Jeg har før set folk som troede de kunne lave sådan en liste ud fra sessions Men det går ikke desværre I princippet må serveren selvfølgelig vide hvilke sessions der eksisterer og hvilker der er døde Men du kan ikke lave en asp side som viser dig disse sessions Hvis du går ind på en asp side og beder om alt der har med sessions at gøre, så får du alt der har med dine sessions at gøre, hvis jeg går der ind får jeg alt der har med mine sessions at gøre Kan du se det? Derfor er en løsning at sætte et felt i databasen til True/False ud fra hver bruger En anden løsning er at lave en applikations variabel som indeholder online brugere Afhængig af hvor mange brugere du har online ad gangen, og hvor stor database tilgang du har ad gangen Så kan man argumentere for det ene eller andet -- Jeg prøver lige stykke et eksempel sammen :o)
Angående punkt nummer 2. Så er vi jo lige vidt - mht at sætte et felt i db til true eller false. Var jo det jeg har gjort fra starten. Kørt deres online status fra et ja/nej felt i db og lavet en online liste ud fra det. Når jeg tager db i brug for at checkke hvem er online eller offline når jeg jo det samme udgangspunkt som fra MANGE kommentarer tilbage. Brugeren vil stadig stå som online hvis brugeren blot lukker browseren indtil han kommer tilbage og logger ind for derefter at logge ordentlig ud.
Begyndte at tænke på session fordi jeg vidste det kunne laves (online - ofline check), og så kan jeg jo stole på session.timeout() til at smide dem som offline. Vidste godt jeg ville få problemer med at lave en online liste ud fra mine sessions, men på den anden side er det så ikke muligt at når... (skal lige sige jeg ikke bruger global.asa i skrivende stund) ...brugeren logger ind bliver han tildelt sit unikke ID fra db i Session("bruger") - for derefter at lave noget øhhh (bær over med mig, er lige vågnet hehe) ligenede med at den checkker hvor mange sessions("bruger") matcher db...
Har squ set en del sites nu der benytter sig af et velfungerende login system. Efter given tid hvis man ikke logger af klarer ( Session.Timeout() vil jeg tro de bruger ) det for dig, men stadig laver de en flot online liste med links og det hele. Ref.: www.hotpeople.dk
Læste din artikkel om Global.asa busschou og jeg må sige den er godt skrevet. Der er kun en ting der forhindrer mig i at bruge den. Login siden skal være i html, det du ikke eftersom jeg benytter meget asp på login siden, og brugeren skal jo have lov til at surfe rundt på sitet uden han behøver at logge ind (så længe det ikke kræves) Point is: Kan ikke stille det sådan op at den første page en bruger kommer til er html.
Damn, laaaaang post.. Også kl 7.40 om morgenen? Nu kommer jeg for sent på arbejde hehe.. Men hvad, det er jo det her der er mit arbejde, at lave websites så mon ikke det går. Det tog mig præcist 15 minutter at skrive alt det her (langsom om morgenen, hvad kan jeg sige :) )
Her er et eksempel ved brug af database Bemærk at din login side bliver nød til at være en *.html fil, for hvis det er en *.asp fil så vil Session_OnStart køres inden brugeren logger ind! ---- global.asa ---- <SCRIPT LANGUAGE=VBScript RUNAT=Server> Sub Application_OnStart ' Global variabel som husker hvor din database ligger Application("db") = "Data Source="&Server.Mappath("database.mdb")&_ ";Provider=Microsoft.Jet.OLEDB.4.0;" End Sub
Sub Application_OnEnd End Sub
Sub Session_OnStart ' Sæt timeout til fx 20min Session.Timeout = 20
' Sæt andre ting du kunne have brug for fx dansk format ' Session.lcid = 1030
' Tag brugernavn og kodeord fra login siden Session("bruger") = Replace(Request.Form("bruger"),"'","''") Session("kode") = Replace(Request.Form("kode"),"'","''") ' Opret database forbindelse Dim Conn, rs Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open Application("db") ' Slå brugernavn og kode op i database Set rs = Conn.Execute("Select * From brugere Where bruger = '"&Session("bruger")&_ "' And kode = '"&Session("kode")&"'") If not rs.eof Then ' Hvis brugeren findes gem da id i en session og sæt brugeren til online i databasen ' Hiv evt andre oplysninger ud i sessions som fx adgang med mere Session("id") = rs("Id") Conn.Execute("Update brugere Set online = True Where Id = "&Session("id")) Else ' Hvis ikke brugeren findes så videresend tilbage til login siden Session.Abandon Response.Redirect "login.html" Conn.Close Set Conn = Nothing End If Conn.Close Set Conn = Nothing End Sub
Sub Session_OnEnd ' Opret databaseforbindelse Dim Conn Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open Application("db") ' Opdater tabel så brugeren sættes til offline Conn.Execute("Update brugere Set online = False Where Id = "&Session("id")) Conn.Close Set Conn = Nothing End Sub </SCRIPT> ---- På din logud side skal du bare kalde Session.Abandon, derved køres Session_OnEnd og databasen opdateres Hvis en bruger lukker sin browser så køres Session_OnEnd når sessionen timer ud efter de antal minutter du har sat På din side hvor du vil liste alle online brugere kan du lave noget ala følgende ---- Dim Conn, rs Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open Application("db") Set rs = Conn.Execute("Select * From brugere Where online = True") //og så et loop som viser brugerne ---- På de enkelte brugeres sider kan du tilsvarende vise om brugeren er online ved at slå op på fx brugernavn ---- Dim Conn, rs Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open Application("db") Set rs = Conn.Execute("Select * From brugere Where bruger = 'ib'") if rs("online") then response.write "ib er online" else response.write "ib er ikke online" end if ---- Jeg håber du kan se ideen i ovenstående Du skal selvfølgelig rette tabel navn og database navn med mere, og også connectionen hvis det er mysql og ikke access Du kan evt også gemme i tabellen hvornår brugeren er logget ud, derved kan du jo så skrive på en brugers side "ib er ikke online men blev sidste set den og den dag klokken det og det"
hey, så ikke lige du havde skrevet i mellem tiden :o) -- Hvis du har læst min artikkel så ved du også at du ikke helt kan stole på session.timeout, det der sker er jo at den forsøger at kald session_onend, og den kan man ikke 110% stole på kører. Dette er jvnf Microsoft, og jeg har ikke selv prøvet det at den ikke kører, og jeg har ikke hørt om nogen statestik på det, men har hørt andre at man kan risikere at den ikke bliver kørt -- Hvordan skal det med sessions virke? Hvis jeg logger ind og lad os sige jeg får Session("bruger") = 1 Hvis du logger ind og lad os sige at du får Session("bruger") = 2 Jeg går ind på siden "visOnlineBrugere.asp" som hiver ud fra database "Select * From brugere Where Id = "&Session("bruger") Ja så får jeg at vide at jeg er online, jeg får ikke at vide at du er online For jeg har _kun_ adgang til min egen session --- Du skriver selv at du har set en del velfungerende systemer, som du tror benytter sig af session.timeout Det _eneste_ sted der kan registrere når en session får timeout er global.asa´s Session_OnEnd Ergo skal det kodes i global.asa Session_OnEnd kaldes umiddelbart inden serveren frigiver brugte resourcer på en given session Hvis min session timer ud så kaldes den for min session Hvis din session timer ud så kaldes den for din session Men min kan ikke se dig og din kan ikke se mig --- Jeg kan sagtens se det smarte i man kunne lave en oversigt over de Session.SessionId der er udgivet på serveren Det er muligt du kan det hvis du selv styrer serveren, men det har jeg desværre ingen forstand på Dog vil du i givet fald kun kunne se det i adminisrationen på serveren og ikke på en asp side --- Mit eksempel i mit sidste indlæg virker,på nær usikkerheden om Session_OnEnd køres, men den usikkerhed må man leve med Den lever de andre sider du kender også med :o) --- Jo det er muligt at ens login side ikke hedder html men asp Så mister man bare det (synes jeg smarte) med at man kan putte det hele i global.asa Du vil i stedet så skulle have en login side hvor du opdaterer databasen Du vil stadig skulle bruge din Session_OnEnd for at registrere et timeout Men denne skal laves om, for alle der ikke er logget ind de vil så også få kørt denne metode Det vil sige at du fx kunne tjekke på om session("bruger") var tom, hvis ikke så er brugeren logget ind og skal logges ud, hvis den er tom så gør du bare ingen ting --- Lad mig høre hvad du mere tænker over inden jeg smækker et eksempel mere sammen :o)
Håber du kan forstå min point i hvad jeg skrev i ovenstående post:
"Login siden skal være i html, det du ikke eftersom jeg benytter meget asp på login siden, og brugeren skal jo have lov til at surfe rundt på sitet uden han behøver at logge ind (så længe det ikke kræves) Point is: Kan ikke stille det sådan op at den første page en bruger kommer til er html."
Men ellers, det jeg er ude efter er et online system, med eller uden sessions. Eneste krav er at vi kommer udenom det med at brugeren fortsat står som online indtil han logger ind og korrekt ud igen hvis kan bare lukker browseren.
Om vi så bruger global.asa med sessions eller hvad vi bruger er underordnet, bare det kommer til at fungere ;)
Her et eksempel på hvordan du gør det når alle sider er asp Og nu har jeg så kun taget det strengt nødvendige med ---- login.asp ---- Session("bruger") = Replace(Request.Form("bruger"),"'","''") Session("kode") = Replace(Request.Form("kode"),"'","''") Dim Conn, rs Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open "Sti til database" Set rs = Conn.Execute("Select * From brugere Where bruger = '"&Session("bruger")&_ "' And kode = '"&Session("kode")&"'") If not rs.eof Then session("id") = rs("id") 'Hvis login er ok sættes brugeren online i tabellen Conn.Execute("Update brugere Set online = True Where Id = "&Session("id")) Else 'giv en fejl response.write "fejl i login" end if --- global.asa --- <SCRIPT LANGUAGE=VBScript RUNAT=Server> Sub Session_OnStart ' Sæt timeout til fx 20min Session.Timeout = 20 End Sub
Sub Session_OnEnd ' da session("id") kun sættes ved korrekt login tjekkes på denne if session("id") <> "" then ' Opret databaseforbindelse Dim Conn Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open "Din_Absolutte_Sti_Til_Databasen" ' Opdater tabel så brugeren sættes til offline Conn.Execute("Update brugere Set online = False Where Id = "&Session("id")) Conn.Close Set Conn = Nothing end if End Sub </SCRIPT> --- Din logud skal stadig blot kalde session.abandon
Okay, men synes det ser ud som om du benytter en access db i dit forslag. Connection strengen er jo anderledes med en MySQL.. Hmm, ser lige om jeg kan bikse noget sammen.
Men stadigvæk, hvordan mener du så jeg kan printe i brugerens profil om han/hun er online/offline ud fra ovenstående eksempel så alle kan se det?
Ahhh.. Har fået for lidt kaffe, selvfølgelig ud fra online feltet i db lol..
hehe ja men jeg har heller aldrig påstået at jeg kender noget til mysql i asp jo ;o) Jeg kender ikke connection strengen, men du må kunne finde en på www.connectionstrings.com som skrevet 10/08-2005 13:14:50 :o) -- Hvis du vil lave en online liste så slår du op i din tabel og siger Select * From tabel Where online = True Så får du alle dem som er online, nogen af dem er måske ikke til stede, for alle der ikke logger ud vil der jo unægtelig gå de der 20 minutter før global.asa logger dem ud -- Hvis du vil vise i en given brugerprofil om vedkommende er online eller ej så slår du brugeren op Du er derfor nød til at have fx brugerens id eller navn altså fx www.dinside.dk/online.asp?bruger=ib Så laver du en Select * From tabel Where bruger = "&request.querystring("bruger") Det burde ikke være noget problem, for normalt for at se en bruger skal man jo klikke på et link. Og normalt vil disse links blive skrevet ud udfra din database hvorved du sætter id eller navn på som querystring i linket
<SCRIPT LANGUAGE=VBScript RUNAT=Server> Sub Session_OnStart ' Sæt timeout til fx 20min Session.Timeout = 1 End Sub
Sub Session_OnEnd ' da session("id") kun sættes ved korrekt login tjekkes på denne if session("bruger") <> "" then ' Opret databaseforbindelse Dim Conn StrConnection StrConnection = "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=sql01.dk; DATABASE=mikejohnsendk; UID=mikejohnsendk; PWD=Eyy79Fn6" Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open strConnection ' Opdater tabel så brugeren sættes til offline Conn.Execute("Update Members Set online = 2 Where MemberID = "&Session("bruger")) Conn.Close Set Conn = Nothing end if End Sub </SCRIPT>
hæhæ ja specielt når det er på en sql server ;o) Anyway Så er problemet jo med global.asa at man ikke kan få en fejlmedelelse, den går kun i serverens log mig bekendt, og den kan man som normal bruger ikke se Derfor kan jeg umulig sige hvad der fejler Min erfaring med access var som tidligere nævnt at med en slags connectionstring så virker det, og med en anden gør det ikke Det er muligt det er det samme for mysql, måske at der skal benyttes en anden driver fx -- PS Den bliver jo kun kørt hvis der eksisterer en session("bruger") , og den er du sikker på du har sat ved login ikke ?
jeg kan se på linket at der findes en ældre driver til remote access til din database, -- "Driver={mySQL};Server=data.domain.com;Port=3306;Option=131072;Stmt=;Database=my-database;Uid=username;Pwd=password;" -- den kunne du evt prøve Hvem har du som udbyder?
hvis ikke det virker så kan jeg desværre ikke hjælpe dig bedre Det må givet fald skyldes enten at databaseforbindelsen går galt, eller selvfølgelig evt fejl i sql´en
Hvis alt andet fejler vil jeg foreslå dig at spørge din support ad :o)
Lovede at skrive herinde hvis jeg fik det til at virke.
Jeg sagde jeg ikke ville give op - og stædighed belønnes. Jeg har fået lavet et scipt vha global.asa der opdaterer databasen til at brugeren er offline ved session.timeout. Denne funktion virker 10 ud af 10 gange (i hvert fald ud fra mine tests)
global.asa -----------
<script language="vbscript" runat="server">
sub session_onstart session.timeout = 1 end sub
sub Session_OnEnd brugerID = Session("bruger") Connection = "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=sql01.dk; DATABASE=mikejohnsendk; UID=mikejohnsendk; PWD=g1EwRiuc" Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open Connection Session.lcid = 1030 'Set locale to Denmark
sqloffline ="Update Members SET Online=0 WHERE MemberID="&brugerID conn.execute(sqloffline)
Virker både hvis brugeren bare lukker browseren uden af logge ud korrekt, virker hvis brugeren surfer videre til et andet site uden at logge ud korrekt og virker også hvis brugeren er inaktiv for længe på sitet (sat til 30 min.)
lol, ja så må du ændre den igen ;o) Det med at det køres hvis brugerne er inaktiv i 30 minutter, så har du vel sat en session.timeout = 30 et sted på sitet eller hvordan? For i din global.asa har du defineret den til 1 minut :o)
Men godt det virker, og der kan man jo ellers også se at eneste forskel til mysql er connectionstringen :o)
session.timeout er sat til 30 i global.asa.. var en ældre version af global.asa jeg postede der.. Men ja, session.timeout er deffineret til 30..
Men det har da ellers taget noget tid at finde ud af.. Det hele handlede jo blot om små tweaks til connection string
Synes godt om
Ny brugerNybegynder
Din løsning...
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.