GUI Browser(client) - Server (03-2008/12-2009/12-2010)
Aanleiding .
In de huidige tijd neemt een gebruiker geen genoegen meer met een simple commandbox .
Het moet muis gestuurd zijn en mogelijk in kleur en voorzien zijn van duidelijke iconen .
Daar bijna ieder window-systeem weer zijn eigen , volstrekt incompatibel , aansturing kent
betekend dit dat je een GUI voor bijna ieder verschillend systeem moet maken .
Zo is MSWindows weer anders dan GTK , welk weer verschilt van QT .
Er zijn , mij , een paar systemen bekent die OS en Window onafhangkelijk zijn .
Een is JAPI . Een windowsysteem dat voor veel toepassingen een wrapper kent naar Java .
De andere is GraphAppl wel een window systeem is gebouwd op MSWindows en XWindows .
Een andere benadering is gebruikt te maken van een Browser welke als besturing het HTML protocol
gebruiken . Dit is geheel OS onafhankelijk . Ofschoon er wel verschil zit in de uitvoering van de
browsers . Mozilla (en wat daar vanaf stamt) houd zich goed aan de W2C afspraken .
IE houd er zo af en toe wel een zeer speciaal idee opna hoe de W2C afspraken worden uitgevoerd .
Safira (Mac) heb ik geen ervaring mee .
Een mooie desktop-toepassing van zo'n Browser interface is die zoals gebruikt door eyeOS .
Mijn idee is dat je een GUI zou moeten kunnen maken door een Browser als uitvoer tegebruiken .
Dit betekend dat je programma een server met HTTP protocol moet gaan bevatten .
Dan kan je programma de uitvoer maken in HTML/CSS en via de server sturen naar de Browser .
De Browser stuurd dan de formulieren terug naar de server . Deze herformateerd deze zodanig
dat je programma ze kan gebruiken als invoer .
!--------------------------------!
!---------! ! !--------! !------------! !
! Browser ! ... < ---- > ... ! ! server ! <--> ! Toepassing ! !
!---------! ! !--------! !------------! !
!--------------------------------!
je in/uit voer je applicatie
Wensen :
1) Eigenlijk wil ik dat we meerdere zelfde applicatie kunnen starten .
2) Tevens wil ik dat als de gebruiker het window waarin de applicatie getoond wordt sluit
dit resulteerd in het gedrag dat de applicatie zich ook afsluit .
3) Eigenlijk wil ik dat het beeindigen van de applicatie ook het window in de browser zich sluit .
--------------------------------------------------------------------------------------------------
Probleem 1) is bedacht dat de gestarte applicatie zoekt naar een vrije poort .
Voor XP vond ik dat 4990-5000 vrij zijn . Waardat gedeffineerd wordt , geen idee .
Want vanaf 5001 worden de aanvragen door XP geweigerd .
Voorbeeld :
data serveradres/'127.0.0.1:'/
serverpoort = 4990
server = 0
c zoek een niet gebruikte poort
do while((server.ge.0).and.(serverpoort.le.5001))
serverpoort=serverpoort+1
write(serveradres(11:14),'(I4,$)')serverpoort
write(6,*)serveradres
c mode = client
mode='c'
server=netwerk_open(serveradres,mode)
c indien gevonden geeft dit fouten aan de server site
c daar er geen HTTP is . Dit wordt gezien als een EOF
if(server.ge.0)call netwerk_close(server)
end do
c mode = server
mode='s'
server=netwerk_open(serveradres,mode)
if(server.lt.0)then
write(6,*)'error cann''t open server'
stop
end if
c start browser
call system('defaultbrowser http://'//serveradres)
c return to application
Dus de browser wordt gestart zodra de server is gestart .
Dit houdt wel in dat de browser als backgroundjob c.q. parallel process moet kunnen worden gestart .
In Linux start je een backgroundjob door achter de commandline een & te zetten .
In Windows start je een backgroundjob door de commandline te beginnen met de opdracht 'start' .
In XP windows geld voor defaultbrowser :
@echo off
start c:\"Program Files\Mozilla Firefox"\firefox.exe %1
In Linux :
#!/bin/sh
firefox @1 &
------------------------------------------------------------------------------------------------------
Het probleem voor 2) is wat ingewikkelder .
Er wordt heel wat over geschreven als je wat zoekt op Internet .
Maar geen van al de aangedragen oplossing werkt echt bevredigend .
Het basis probleem is dat een Browser geen informatie terug geeft als een gebruiker de browser sluit .
Opzich logisch als je bedenkt dat de gebruiker feitelijk de browser stopt , hoe kan deze dan wat doen .
Omdit niet alte ingewikkeld te krijgen heb ik teruggegrepen op een heel oud principe n.l. clock-tick .
De server staat de heletijd te kijken of er een aanvraag komt van de Browser .
(Hiertoe moet de onderliggende ACCEPT() functie niet geblokeerd is !
Je kunt de socket openen met een UNBLOCK of de SELECT() functie gebruiken met een time-out .
Het openen van een UNBLOCK socket geeft 100% cpu bezetting in XP .
Daarom gebruik ik de select() met een time-out van 1 sec .
)
Laat de browser , als er een tijd niets gebeurd zelf , een (klok)tick naar de server sturen .
Dit geeft de server de informatie dat de gebruiker het window nog aktief heeft (127.0.0.1:4992/tick) .
De server kan opgrond van deze aanvraag de time-out weer op 0 zetten en een antwoord sturen .
Voor dit antwoord heeft het HTTP protocol een dummy antwoord wat de aanwezige pagina niet wijzigd .
Hiervoor zorg de response header HTTP/1.1 204 OKE .
Komt er gedurende enige tijd geen tick dan start de server een process om de applicatie te sluiten .
Voorbeeld server accept :
client=0
timeout=time()+75
do while(client.eq.0)
c mode = accept
client=netwerk_open(server,mode)
if (timeout.le.time())then
c time-out error : close server and dump program
call netwerk_close(server)
call netwerk_end()
write(6,*)'Progam abort due Time-Out at '
stop
end if
end do
De server heeft een time-out van 60+15 sec dit daar de browser een tick geeft om de 60 sec .
Ieder antwoord wat gestuurd wordt naar de browser met HTTP1.1/ 200 OKE moet nu een script meekrijgen
dat om de 60 sec een tick stuurd als er niet anders gebeurd is .
Dit wordt gedaan door in het antwoord onderstaand java-script meetesturen .
<script Language=JavaScript>
function tik() {setTimeout("tik()",60000);window.location.pathname="/tick"}
setTimeout("tik()",60000)
</script>
-----------------------------------------------------------------------------------------------------
Probleem 3) is niet in alle browser optelossen .
In IE kun je een window.opener="onzin";window.close() het venster sluiten .
In de Mozilla versie is dit na versie 2.x en hoger niet meer mogelijk .
Het argument van de Mozilla groep is dat alleen de gebruiker een venster kan sluiten .
Behalve als een venster is gemaakt door een script dan kan deze ook door een script worden gesloten .
-----------------------------------------------------------------------------------------------------
Subroutine fserver.f
Allereerst moet je de server initieeren d.m.v. call netserver .
Dit opend een Webbrowser met http://ipadres:poort .
De kommunikatie gaat via een commonblok /serverdata/cmd,cmdbuf
cmd geeft de opdracht weer en cmdbuf de data .
Je hoofd programma is een lus welke begin met :
call command_from_client
Op grond van cmd en/of cmdbuf moet je nu een antwoord geven .
Dit kan zijn :
1 regel text call responsetext(text-line)
1 bestand call responseclient(file-name)
of een intern gemaakt html antwoord
call write_open_client(aanhef)
gevolgd door de teschrijven text via het common cmdbuf
call write_client_buf
of d.m.v. een text regel
call write_client(text-line)
afsluiten met (wat ook een