Cursus Raku / Functioneel, concurrent, reactief en webprogrammeren / Webprogrammeren / Een eenvoudige HTTP-server
Veel verzoeken bedienen
De server op de vorige pagina handelde één enkel verzoek af en stopte
daarna. Een echte server blijft draaien en beantwoordt de ene client na
de andere. Wikkel de stappen accepteren-lezen-antwoorden in een
loop — en omdat de lus de eromheen gedeclareerde variabelen
deelt, kun je toestand tussen verzoeken bewaren. Hier telt de server
zijn klanten en vertelt hij elk zijn nummer:
my $listener = IO::Socket::INET.new(
:listen,
:localhost('127.0.0.1'),
:localport(8080),
);
my $customer = 0;
loop {
my $conn = $listener.accept;
$conn.recv;
$customer++;
# a qq:to heredoc makes a tidy template — the variable interpolates straight in
my $body = qq:to/END/;
Hello!
You are customer number $customer.
Thanks for visiting.
END
# send the header first, then the body, as two separate writes
$conn.print("HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n");
$conn.print($body);
$conn.close;
}.accept blokkeert tot een client
verbinding maakt en geeft daarna een verse socket voor dat ene gesprek
terug. Omdat $customer buiten de lus leeft, overleeft die
van het ene verzoek naar het volgende: de eerste bezoeker is klant
1, de tweede 2, enzovoort. De lus eindigt uit
zichzelf nooit, dus de server blijft draaien tot je hem met Ctrl-C
stopt.
Twee details zijn het opmerken waard:
Het antwoord wordt in twee delen geschreven. De eerste
.printverstuurt de HTTP-header — de statusregel, het contenttype en de lege regel die de headers beëindigt. De tweede verstuurt de body. HTTP kan het niets schelen of die in één of in meerdere schrijfacties aankomen, dus ze splitsen houdt het vaste protocolwerk gescheiden van het deel dat werkelijk verandert.De body komt uit een sjabloon.
qq:to/END/is een heredoc — eenqq-string die tot de regelENDloopt. Hij beslaat meerdere regels en interpoleert$customernet als elke string met dubbele aanhalingstekens, wat er een net klein sjabloongereedschap van maakt om een antwoord op te bouwen. (Het is een van de aanhalingsconstructies van eerder in de cursus.)
Maak een paar keer verbinding om de teller te zien klimmen:
$ curl http://127.0.0.1:8080/
Hello!
You are customer number 1.
Thanks for visiting.
$ curl http://127.0.0.1:8080/
Hello!
You are customer number 2.
Thanks for visiting.Verzoeken zo na elkaar afhandelen is de eenvoudigste soort server. Een productieserver zou elke verbinding ook op een eigen thread of promise bedienen, zodat een trage client de andere niet kan ophouden — maar het hart ervan is precies deze lus: accepteren, lezen, antwoorden, herhalen.
Cursusnavigatie
← Antwoorden op een verzoek | Het pad in hoofdletters →
💪 Of ga direct naar de
oefening bij deze sectie.