Corso di Raku / Programmazione funzionale, concorrente, reattiva e web / Programmazione web / Un semplice server HTTP
Servire molte richieste
Il server della pagina precedente gestiva una sola richiesta e poi si
fermava. Un server vero continua a girare, rispondendo a un client dopo
l’altro. Avvolgi i passi accetta-leggi-rispondi in un loop
— e poiché il ciclo condivide le variabili dichiarate attorno a esso,
puoi mantenere uno stato fra le richieste. Qui il server conta i propri
clienti e dice a ciascuno il proprio numero:
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 blocca finché un client non si
connette, poi restituisce un socket fresco per quella singola
conversazione. Poiché $customer vive fuori dal ciclo,
sopravvive da una richiesta alla successiva: il primo visitatore è il
cliente 1, il secondo il 2 e così via. Il
ciclo non finisce mai da solo, quindi il server resta su finché non lo
fermi con Ctrl-C.
Vale la pena notare due dettagli:
La risposta è scritta in due parti. Il primo
.printinvia l’intestazione HTTP — la riga di stato, il tipo di contenuto e la riga vuota che chiude le intestazioni. Il secondo invia il corpo. A HTTP non importa se questi arrivino in una scrittura o in parecchie, quindi dividerli tiene separato il testo fisso del protocollo dalla parte che cambia davvero.Il corpo viene da un modello.
qq:to/END/è un heredoc: una stringaqqche corre fino alla rigaEND. Si estende su più righe e interpola$customercome qualunque stringa fra virgolette doppie, il che ne fa un piccolo e ordinato strumento di templating per costruire una risposta. (È uno dei costrutti di quoting visti prima nel corso.)
Connettiti qualche volta per veder salire il contatore:
$ 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.Gestire le richieste una dopo l’altra così è il genere di server più semplice. Un server di produzione servirebbe anche ogni connessione su un proprio thread o promise, così che un client lento non possa trattenere gli altri — ma il cuore è esattamente questo ciclo: accetta, leggi, rispondi, ripeti.
Navigazione del corso
← Rispondere a una richiesta | Il percorso in maiuscolo →
💪 Oppure vai direttamente all’esercizio
di questa sezione.