- Index
Op de webpagina moet de gebruiker enkel deze eevoudige kode opnemen op de plaats waar de teller moet komen:
<script src=http://myserver.com/cgi-bin/counter></script>Een enkele programma zorgt voor alle tellers op alle pagina's van al je gebruikers:
DEFWORD a-z
FUNCTION PBMAIN()
$aa = "document.write('": $zz = "');" ' De browser verwacht javascript, geen HTML,
homepage$ = ENVIRON$("HTTP_REFERER") ' We moeten de output "inpakken".
ipaddr$ = ENVIRON$("REMOTE_ADDR")
filename$ = $userpath + PARSE$(homepage$, "/", -2) + "_" + PARSE$(homepage$, "/", -1) + ".txt"
' We maken een filenaam aan gebaseerd op de gebruiker (user directory)
' en de pagina zelf (referer)
' We zouden ook kunnen testen dat de domein name wel van onze server afkomstig is zodat
' niet-klanten onze tellers niet gebruiken.
er = ERRCLEAR
OPEN filename$ FOR INPUT AS #1
IF ERRCLEAR THEN
count = 0
ELSE
LINE INPUT #1, count$: count = VAL(count$)
LINE INPUT #1, oldipaddr$
CLOSE #1
END IF
IF ipaddr$ <> oldipaddr THEN ' In geval de gebruiker meer dan één teller op zijn pagina zou plaatsen
INCR count ' of de pagina meermalen na elkaar zou inlezen om de tellen kunstmatig op te voeren
OPEN filename$ FOR OUTPUT AS #1
PRINT #1, count
PRINT #1, ipaddr$
CLOSE #1
END IF
OPEN ENVIRON$("CGI_STDOUT") FOR OUTPUT AS #1
PRINT #1, $aa count $zz
END FUNCTION
|
Een grafische teller is even gemakkelijk: maak 10 gifs aan, allemaal met dezelfde hoogte en met een transparante achtergrond en noem ze 0.gif, 1.gif, enz. Dit is de kode:
....
OPEN ENVIRON$("CGI_STDOUT") FOR OUTPUT AS #1
count$ = FORMAT$(count, "000000")
FOR i = 1 TO 6
PRINT #1, $aa "<img src=http://myserver.com/counterpix/" MID$(count$, i, 1) ".gif align=left>" $zz
NEXT i
END FUNCTION
|
TYPE orderlayout
ok AS BYTE ' Om een order te wissen maken we order.ok = 0
customer AS DWORD ' in plaats van het record te wissen.
date AS STRING * 6 ' Veel gemakkelijker te recupereren...
trackingnumber AS DWORD
... ' enz (alle velden van het order komen hier)
message AS DWORD
END TYPE
DIM order AS orderlayout
|
Hoe kunnen we een volledig bericht in 4 bytes schrijven? Heel eenvoudig:
...
IF LEN$(msg$) THEN
order.message = writerecord($path + "order.mes", msg$)
ELSE
order.message = 0
END IF
OPEN $path + "order.dat" FOR RANDOM ACCESS WRITE AS #1 LEN = LEN(order)
PUT #1, iorder, order
CLOSE #1
...
|
En zo lezen we een eventueel bericht:
...
OPEN $path + "order.dat" FOR RANDOM ACCESS READ AS #1 LEN = LEN(order)
GET #1, iorder, order
CLOSE #1
IF order.message THEN
msg$ = readrecord$($path + "order.mes", order.message)
ELSE
msg$ = ""
END IF
...
|
Bericht wijzigen? Oude wissen en nieuwe aanmaken:
...
OPEN $path + "order.dat" FOR RANDOM AS #1 LEN = LEN(order)
GET #1, iorder, order
IF order.message THEN
killrecord($path + "order.mes", order.message)
END IF
order.message = writerecord($path + "order.mes", msg$)
PUT #1, iorder, order
...
|
Alle handelingen gebeuren in writerecord, readrecord en killrecord. Dit is de source:
| ||||||
Een klein minpunt is dat je geen $CRLF in je bericht kan hebben, aangezien deze combinatie als recordseparator wordt gebruikt. Indien je verder toch met HTML zal werken, kan je $CRLF omzetten naar <BR> voor het schrijven.
Het is veel efficienter om records achteraan het bestand bij te voegen dan de gewijzigde records tussen te voegen en de inhoud van de rest van het bestand te verschuiven. Na een tijdje bekom je wel een bestand met ongebruikte delen. Dit is echter geen groot probleem, omdat het bestand met direct access werkt (directe toegang tot iedere record). Maar het is altijd mogelijk de gaten op te vullen:
OPEN $path + "order.mes" FOR INPUT ACCESS READ SHARED AS #1
i = 0
WHILE NOT EOF(1)
LINE INPUT #1, a$
IF TRIM$(a$) = "" THEN
i = i + LEN(a$) + 2
END IF
WEND
j = LOF(1)
CLOSE #1
percent = i * 100 / j
IF percent > 40 THEN
OPEN $path + "order.dat" FOR RANDOM ACCESS READ WRITE AS #1 LEN = LEN(order)
FOR iorder = 1 TO norder
GET #1, iorder, order
IF order.ok and order.message THEN
a$ = TRIM$(readrecord$($path + "order.mes", order.message))
IF LEN(a$) THEN
order.message = writerecord($path + "order.tmp", a$)
ELSE
order.message = 0
PUT #1, iorder, order
END IF
NEXT iorder
CLOSE #1
KILL $path + "order.mes"
NAME $path + "order.tmp" AS $path + "order.mes"
END IF
|
Deze verwerking doe je best als de server minder belast is. Voor een webtoepassing is het aangeraden de database te locken gedurende de compressie. En natuurlijk maak je gebruik van de gelegenheid om eveneens een back-up te maken.
De volledige compressie is zo gebeurd. Op een oude server (Dell Poweredge 2450, PII 600 MHz, 512MB RAM, SCSI RAID 0-1) duurt de compressie minder dan 10 seconden voor een berichtenbestand van 1 MB (dus duizenden berichten).
Individuele landingspage bezoekers: