Härmed skulle jag vilja utlysa en liten tävling! Finn 5 fel i min global.asa kod, eller ja så många fel som du kan hitta. Den som hittar flest fel vinner inget, och den som hittar näst flest fel vinner inte heller något. Den som hittar minst fel blir också utan vinst. Den enda som vinner något på detta verkar vara jag som förhoppningsvis får en felfri fil. Mycket nöje!
<script language=VBScript runat=Server>
Sub Session_OnStart()
Session.Timeout = 15
Session("ChatInitialised") = True
Application.Lock
strName = Request.ServerVariables("SCRIPT_NAME")
Select Case LCase(Left(strName,5))
Case "/bsai"
Application("NumUsers") = Application("NumUsers") + 1
Case "/80ss"
Application("NumUsers2") = Application("NumUsers2") + 1
End Select
Application.Unlock
End Sub
Sub Session_OnEnd()
Dim vChatName, vChatUsers, vChatMoods, vUserCount
Dim vRoomNo
Dim m, n
vRoomNo = Session("RoomNo")
vChatName = "" & Session("ChatName")
If vChatName <> "" Then
Application.Lock
vUserCount = CLng(Application("UserCount" & vRoomNo))
If vUserCount < 2 Then
vChatUsers = ""
vChatMoods = ""
vUserCount = 0
Else
vChatUsers = Application("ChatUsers" & vRoomNo)
vChatMoods = Application("ChatMoods" & vRoomNo)
For n = 0 To vUserCount - 1
If vChatUsers(n) = vChatName Then
For m = n To vUserCount - 2
vChatUsers(m) = vChatUsers(m+1)
vChatMoods(m) = vChatMoods(m+1)
Next
vUserCount = vUserCount - 1
Redim Preserve vChatUsers(vUserCount)
Redim Preserve vChatMoods(vUserCount)
Exit For
End If
Next
End If
Application("ChatUsers" & vRoomNo) = vChatUsers
Application("ChatMoods" & vRoomNo) = vChatMoods
Application("UserCount" & vRoomNo) = vUserCount
AddLineToChat vRoomNo, "**" & vChatName & " has left (timed out)**"
Session("ChatName") = ""
If vUserCount = 0 Then
Application("ChatLines" & vRoomNo) = ""
Application("ChatLineCount" & vRoomNo) = 0
Application("ChatMaxLines" & vRoomNo) = 0
End If
Application.Unlock
End If
Application.Lock
strName = Request.ServerVariables("SCRIPT_NAME")
Select Case LCase(Left(strName,5))
Case "/bsai"
Application("NumUsers") = Application("NumUsers") - 1
Case "/80ss"
Application("NumUsers2") = Application("NumUsers2") - 1
End Select
Application.Unlock
username = Session("username")
ConnectStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("db/membersdb.mdb")
Dim StatusConn
Set StatusConn = Server.CreateObject("ADODB.Connection")
StatusConn.Open ConnectStr
Set rsUpdate = Server.CreateObject("ADODB.Recordset")
rsUpdate.Open "users WHERE Username = '" & username & "' ", StatusConn, 3, 3
rsUpdate("Countsessions") = False
rsUpdate.Update
rsUpdate.Close
Set rsUpdate = Nothing
StatusConn.Close
Set StatusConn = Nothing
Session.Abandon
Response.Cookies("username") = ""
End Sub
Sub AddLineToChat (ByVal vRoomNo, ByVal vNewLine)
Dim vCurrentLine, vChatLines, vMaxLines
vCurrentLine = Application("ChatLineCount" & vRoomNo)
vChatLines = Application("ChatLines" & vRoomNo)
vMaxLines = Application("ChatMaxLines" & vRoomNo)
vCurrentLine = vCurrentLine + 1
If vCurrentLine > vMaxLines Then
vMaxLines = vMaxLines + 500
If vCurrentLine = 1 Then
Redim vChatLines(vMaxLines)
Else
Redim Preserve vChatLines(vMaxLines)
End If
Application("ChatMaxLines" & vRoomNo) = vMaxLines
End If
vChatLines(vCurrentLine - 1) = vNewLine
Application("ChatLines" & vRoomNo) = vChatLines
Application("ChatLineCount" & vRoomNo) = vCurrentLine
End Sub
</script>
Håll tävlingarna till Caféet, eller åtminstone någon annanstans där de hör hemma. ;) Jag ser inget felmeddelande eller ens en antydan på att din fil inte fungerar, vad exakt är problemet?
Är det något som inte fungerar i filen? Det enda jag ser är att du har en server.mappath i sub:en Session_OnEnd. Det kommer inte fungera, beskåda följande tråd.
Nog hör väl mitt inlägg hör hemma i ASP-forumet alltid. Tävling och tävling, ville bara skoja till det lite. Tror ändå knappast att de i Cafe-forumet kan så mycket asp iaf... Fixade just det där med mappath med ditt tidigare inlägg, för övrigt ett mycket bra inlägg. Enda problemet nu är att "Application("NumUsers")" inte drar av användare från variabeln då sessionen gått ut. Det gjorde den tidigare. Kan du kolla lite extra på den avdelningen:
Application.Lock
strName = Request.ServerVariables("SCRIPT_NAME")
Select Case LCase(Left(strName,5))
Case "/bsai"
Application("NumUsers") = Application("NumUsers") - 1
Case "/80ss"
Application("NumUsers2") = Application("NumUsers2") - 1
End Select
Application.Unlock
he, he ... va ju jag som kom med förslaget med SCRIPT_NAME ... ser inge vidare ut nu. Varför? Jo, när besökarens Session timas ut vart är besökaren då???
Inte på denna sida :r
Har en "VisitorOnline" lösning liggandes hemma ..... ska leta i gömmorna om jag kan hitta den :e
Bygger på ett recordset object som är sparat i en Application-variabel
Den lösningen kan erbjuda lite mer info om besökarna som är online.
När du säger att det inte ser bra ut, menar du då bara visitors online lösningen för OnEnd eller även motsvarande i OnStart?
Men gäller inte global.asa för alla sidor så att säga. Alltså, det som står i den kan köras oavsett vart på sidan man befinner sig? Eller inte? Har säkert fel...
Vad bra! Leta gärna fram en idiotsäker "Visitors Online"-lösning till mig.
Också, en databas-sträng i global.asa gäller väl från den filen och inte från den sidan som använder koden i global.asa? Typ om databaserna ligger en nivå under wwwroot (som global.asa ligger i) ska väl strängen se ut "../db/sida/db.mdb"
Det jag menade med att det inte såg ngt vidare ut är att besökaren oftast inte är kvar på siten när Session_OnEnd triggas ... dvs, du kan inte få ngt värde från R.SV(SCRIPT_NAME)
Session_OnStart triggas när besökaren kommer till siten, dvs vid första requesten efter en sida.
Sparar du då ngt i Application-objektet så nås det över alla sidor.
Brukar själv använda mig av att spara connstrings i application variabler.
Tillbaka till problemet.
Vet inte om den är "idiotsäker" men än så har jag inte hittat ngt fel i den :e
global.asa:
========
<OBJECT
RUNAT="Server"
SCOPE="Application"
ID="activeUsers"
PROGID="ADODB.Recordset">
</OBJECT>
<OBJECT
RUNAT="Server"
SCOPE="Application"
ID="activeUsers2"
PROGID="ADODB.Recordset">
</OBJECT>
<script language="VBScript" runat="server">
Sub Application_OnStart()
Call CreateFields(activeUsers)
Call CreateFields(activeUsers2)
End Sub
Sub Session_OnStart()
Dim strCase
strCase = LCase(Left(Request.ServerVariables("SCRIPT_NAME"),5))
Select Case strCase
Case "/test"
'## -- kontrollera om vi har ett recordset för att lägga till aktiva besökare --
If CStr(activeUsers.State) = "0" Then Call CreateFields(activeUsers)
Call AddUser(activeUsers, strCase)
Case Else
'## -- kontrollera om vi har ett recordset för att lägga till aktiva besökare --
If CStr(activeUsers2.State) = "0" Then Call CreateFields(activeUsers2)
Call AddUser(activeUsers2, strCase)
End Select
End Sub
Sub Session_OnEnd()
Call DeleteUser(activeUsers)
Call DeleteUser(activeUsers2)
End Sub
Sub Application_OnEnd()
'## -- do nothing --
End Sub
'## -- skapa fälten i recordsetet --
Sub CreateFields(rst)
With rst
.CursorType = 3
.LockType = 3
.Fields.Append "SessionID", 200, 20
.Fields.Append "Site", 200, 5
.Open
End With
End Sub
'## -- lägg till besökare som online --
Sub AddUser(rst, sSite)
rst.AddNew
rst("SessionID") = Session.SessionID
rst("Site") = sSite
rst.Update
End Sub
'## -- ta bort besökare från online-listan --
Sub DeleteUsers(rst)
rst.MoveFirst
Do Until rst.EOF
If CStr(Session.SessionID) = CStr(rst("Site")) Then
rst.Delete
rst.Update
rst.MoveLast
Exit Do
End If
rst.MoveNext
Loop
End Sub
</script>
När du sedan vill komma åt antalet online på respektive sida/sidor:
Online: <% =activeUsers.RecordCount%>
'## -- eller --
Online: <% =activeUsers2.RecordCount%>
du får labba med det hur du vill ...
som du ser kan flera fält skapas såsom Username etc och man kan då göra rätt "smutta" online-listor, vid vilken sida varje besökare är på m.m, m.m ...
SessionID är ju sessionens unika id och Site vilken site som besökaren kommer till.
I strCase sparas de fem första tecknen från vilken sida besökaren är.
Sedan kommer en Select Case sats som bestämmer vilken av de 2 recordseten som ska uppdateras. Då kallas Subben AddUser() och strCase sparas till fältet Site och SessionID'et till fältet SessionID
I session_onend så loopas recordseten igenom och fältet sessionid matchas mot Session.SessionID som timas ut och hittas en match så tas den posten bort.
Om du vill utöka data som ska sparas är det bara att skapa flera fält i recordseten.
Kika i subben CreateFields(rst)
För att lägga till fler fält:
'## -- skapa fälten i recordsetet --
Sub CreateFields(rst)
With rst
.CursorType = 3
.LockType = 3
.Fields.Append "SessionID", 200, 20
.Fields.Append "Site", 200, 5
'## -- fieldname, fieldtype, field -length
[b].Fields.Append "NewDataField", 200, 255[/b]
.Open
End With
End Sub
sedan för i subben AddUser så lägger du till ett argument med data som ska sparas:
'## -- lägg till besökare som online --
Sub AddUser(rst, sSite, [b]sNewData[/b])
rst.AddNew
rst("SessionID") = Session.SessionID
rst("Site") = sSite
[b]rst("NewDataField") = sNewData[/b]
rst.Update
End Sub
När du sedan i Session_OnStart anropar subben AddUser så passar du även in den nya datan
Nu ser min .asa ut enligt nedan. Tyvärr drabbas severn av "HTTP Error 500-12 Application Restarting
Internet Information Services" då man uppdaterar sin .asa eller efter ett tag, även om det fungerar först. Kikade lite på MSDN och hittade http://support.microsoft.com/default.aspx?scid=kb;en-us;Q302424 Men på webbhotellet säger man att de inte kör med antivirus program på servern. Dessutom minskar aldrig räknaren, precis som om Session_OnEnd aldrig körs eller att funktionen aldrig anropas. Vad är fel???
<object runat="Server" scope="Application" id="ActiveUsers1" progid="ADODB.Recordset"></object>
<object runat="Server" scope="Application" id="ActiveUsers2" progid="ADODB.Recordset"></object>
<object runat="Server" scope="Application" id="ActiveUsers3" progid="ADODB.Recordset"></object>
<script language="VBScript" runat="server">
Sub CreateFields(rst)
With rst
.CursorType = 3
.LockType = 3
.Fields.Append "SessionID", 200, 20
.Fields.Append "Site", 200, 5
.Open
End With
End Sub
Sub DeleteUsers(rst)
rst.MoveFirst
Do Until rst.EOF
If CStr(Session.SessionID) = CStr(rst("Site")) Then
rst.Delete
rst.Update
rst.MoveLast
Exit Do
End If
rst.MoveNext
Loop
End Sub
Sub AddUser(rst, sSite)
rst.AddNew
rst("SessionID") = Session.SessionID
rst("Site") = sSite
rst.Update
End Sub
Sub Application_OnStart()
Call CreateFields(ActiveUsers1)
Call CreateFields(ActiveUsers2)
Call CreateFields(ActiveUsers3)
End Sub
Sub Session_OnStart()
Dim strCase
strCase = LCase(Left(Request.ServerVariables("SCRIPT_NAME"),5))
Select Case strCase
Case "/bsai"
If CStr(ActiveUsers2.State) = "0" Then Call CreateFields(ActiveUsers2)
Call AddUser(ActiveUsers2, strCase)
Case "/80ss"
If CStr(ActiveUsers3.State) = "0" Then Call CreateFields(ActiveUsers3)
Call AddUser(ActiveUsers3, strCase)
Case Else
If CStr(ActiveUsers1.State) = "0" Then Call CreateFields(ActiveUsers1)
Call AddUser(ActiveUsers1, strCase)
End Select
End Sub
Sub Session_OnEnd()
Call DeleteUser(ActiveUsers1)
Call DeleteUser(ActiveUsers2)
Call DeleteUser(ActiveUsers3)
End Sub
Sub Application_OnEnd()
End Sub
</script>
Sub Session_OnEnd()
Call DeleteUser(ActiveUsers1)
Call DeleteUser(ActiveUsers2)
Call DeleteUser(ActiveUsers3)
End Sub
Körs inte även ActiveUsers2 och ActiveUsers3 om tex. Sessionen för ActiveUsers1 går ut? Det är ju inte bra. Kan man på samma sätt som i Session_OnStart kolla i Session_OnEnd vilken mapp som sessionen gäller för?
Hur då ändra rst.Delete till rst.Delete 1? Problemet är att räknaren nu börjat hamna på ex. -3 besökare. Och på webbhotellet säger man att allt står rätt till. Inte konstigt att man sliter håret av sig...
ehhh, inte tror jag att den koden skulle kunna göra så att antalet besökare blir -3 ....
Ett recordset har ju 0 eller fler poster i sig ..... skulle vilja se ett recordset som har negativt antal poster :e
Väl med det klassiska, Application("users") = Application("users") - 1 kan det fenomenet uppstå.