Curso de Raku / Programación funcional, concurrente, reactiva y web / Programación web / Un servidor HTTP sencillo
Atender muchas peticiones
El servidor de la página anterior atendía una sola petición y después
se detenía. Un servidor real sigue corriendo, respondiendo a un cliente
tras otro. Envuelve los pasos de aceptar, leer y responder en un
loop y, como el bucle comparte las variables declaradas a
su alrededor, puedes conservar estado entre peticiones. Aquí el servidor
cuenta a sus clientes y le dice a cada uno su número:
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 se bloquea hasta que un cliente
conecta, y devuelve entonces un socket nuevo para esa conversación
concreta. Como $customer vive fuera del bucle, sobrevive de
una petición a la siguiente: el primer visitante es el cliente
1, el segundo el 2, y así sucesivamente. El
bucle no termina nunca por sí solo, así que el servidor se mantiene en
pie hasta que lo detienes con Ctrl-C.
Merece la pena fijarse en dos detalles:
La respuesta se escribe en dos partes. El primer
.printenvía la cabecera HTTP: la línea de estado, el tipo de contenido y la línea en blanco que cierra las cabeceras. El segundo envía el cuerpo. A HTTP le da igual que estos lleguen en una escritura o en varias, así que separarlos mantiene aparte el formulismo fijo del protocolo de la parte que realmente cambia.El cuerpo viene de una plantilla.
qq:to/END/es un heredoc: una cadenaqqque se extiende hasta la líneaEND. Abarca varias líneas e interpola$customerigual que cualquier cadena entre comillas dobles, lo que la convierte en una pulcra herramienta de plantillas para construir una respuesta. (Es una de las construcciones de entrecomillado vistas antes en el curso.)
Conéctate unas cuantas veces para ver subir el contador:
$ 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.Atender las peticiones una tras otra de este modo es la clase de servidor más sencilla. Un servidor de producción atendería además cada conexión en su propio hilo o promesa, de modo que un cliente lento no pueda retener a los demás, pero su corazón es exactamente este bucle: aceptar, leer, responder, repetir.
Navegación del curso
← Responder a una petición | La ruta en mayúsculas →
💪 O ve directamente al ejercicio de
esta sección.