webForumDet fria alternativet

Finn 5 fel i global.asa

ASP

22 svar · 606 visningar · startad av bigsky

Medlem sedan maj 2002821 inlägg
Frågan#1

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>
Medlem sedan feb. 200112 078 inlägg
#2

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.

Medlem sedan maj 2002821 inlägg
#3

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
Medlem sedan feb. 200112 078 inlägg
#4

Är du helt säker på att villkoret blir uppfyllt överhuvudtaget, dvs blir verkligen värdet '/bsai' eller '/80ss'?

RED. Feltänkt.

Medlem sedan maj 2002821 inlägg
#5

Jodå, det funkar ju bra i onstart subben.

Medlem sedan mars 20002 836 inlägg
#6

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.

cya,
PatrikB

Medlem sedan maj 2002821 inlägg
#7

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"

Medlem sedan mars 20002 836 inlägg
#8

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 ...

cya,
PatrikB

Medlem sedan maj 2002821 inlägg
#9

Verkar ju bra det där. Ska prova den. Kan du förklara lite mer. Vad är tex. SessionID och Site? Hur skulle det se ut om man vill lagra sidan de är på?

Medlem sedan mars 20002 836 inlägg
#10

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.

cya,
PatrikB

Medlem sedan mars 20002 836 inlägg
#11

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

cya,
PatrikB

Medlem sedan maj 2002821 inlägg
#12

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>
Medlem sedan mars 20002 836 inlägg
#13

deleten checkar mot fel fält ... så går det när man klipper och klistrar :o

If CStr(Session.SessionID) = CStr(rst("Site")) Then

ska ju vara

If CStr(Session.SessionID) = CStr(rst("SessionID")) Then

500-12 error kan jag tyvärr inte hjälpa dig med.
Har du kört global.asa tidigare utan problem?

cya,
PatrikB

Medlem sedan maj 2002821 inlägg
#14

Jo, det har inte varit några problem tidigare. Men det beror inte på din kod dock. Eftersom att den fungerade först, error 500-12 kom senare.

Medlem sedan maj 2002821 inlägg
#15

Nej, det fungerar inte. Varken lokalt eller på webbhotellet. Räknaren fortsätter att sätta besöksrekord, dvs att den aldrig subtraherar besökare.

Medlem sedan maj 2002821 inlägg
#16

Även om jag har:

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?

Medlem sedan mars 20002 836 inlägg
#17

Nopez .... det går inte eftersom när sessionen timar ut så finns oftast inte besökaren kvar på sidan.

Hur ska det då gå till att få fram vilken sida besökaren är på......

Prova att i Subben DeleteUser ta bort rst.Update .... ska inte behövas och ändra rst.Delete till rst.Delete 1

Finns många maskiner som har haft problem att trigga Session_OnEnd .... varför har de lärda språkat om länge ....

cya,
PatrikB

Medlem sedan maj 2002821 inlägg
#18

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...

Medlem sedan mars 20002 836 inlägg
#19

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å.

cya,
PatrikB

Medlem sedan maj 2002821 inlägg
#20

Hur då ändra rst.Delete till rst.Delete 1?

Ska jag skapa tre olika rst.Delete? Ett för varje räknare?

270 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
144 ms — hämta tråd, inlägg och bilagor (db)
124 ms — ändringar (db)