# 3.3 Como trabaja Go con la web Hemos aprendido a utilizar el paquete `net/http` para construir un sencillo servidor web en la sección anterior, pero todos los principios de trabajo son las mismas que hemos hablado en la primera sección de este capítulo . ## Algunos conceptos de los principios de trabajo web Request: solicitar datos de los usuarios, incluyendo la POST , GET, la Cookie y la URL. Response: datos de respuesta desde el servidor a los clientes. Conn: conexiones entre clientes y servidores. Handler: lógica para la gestión de solicitudes y respuestas de productos. ## Mecanismo de funcionamiento del paquete http La siguiente imagen muestra el flujo de trabajo del servidor web de Go. ![](images/3.3.http.png?raw=true) Figura 3.9 flujo de trabajo http 1. Crear socket, escuchar en un puerto y esperar a los clientes . 2. Aceptar peticiones de los clientes . 3. Tramitar las solicitudes, leer el encabezado HTTP, si se utiliza el método POST, también es necesario para leer los datos en el cuerpo del mensaje y enviarlos a los controladores. Por último, devolver los datos de respuesta a los clientes. Una vez que conocemos las respuestas a las preguntas siguientes , es fácil saber cómo funciona la web en Go. - ¿Cómo escuchar un puerto? - ¿Cómo aceptar peticiones de cliente ? - ¿Cómo asignar controladores ? En la sección anterior vimos que Go utiliza ListenAndServe para manejar estas etapas: inicializar un objeto de servidor , llamar a net.Listen( "tcp" , addr ) para configurar un puerto TCP de escucha y escuchar a la dirección y el puerto específico. Vamos a echar un vistazo a el código fuente del paquete `http`. ``` //Build version go1.1.2. func (srv *Server) Serve(l net.Listener) error { defer l.Close() var tempDelay time.Duration // how long to sleep on accept failure for { rw, e := l.Accept() if e != nil { if ne, ok := e.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay) time.Sleep(tempDelay) continue } return e } tempDelay = 0 c, err := srv.newConn(rw) if err != nil { continue } go c.serve() } } ``` ¿Cómo aceptamos las peticiones de un cliente después que iniciamos a escuchar en un puerto? En el código fuente , podemos ver que se llama `srv.Serve(net.Listener)` para manejar peticiones de clientes. En el cuerpo de la función hay un `for{}`, se acepta la solicitud, se crea una nueva conexión y, a continuación, se inicia un nuevo goroutine , y pasa los datos de solicitud a esta goroutine: `go c.serve()`. Así es como Go es compatible con alta concurrencia, y cada goroutine es independiente. ¿Cómo usamos las funciones específicas para controlar las solicitudes? `conn` analiza la solicitud `c.ReadRequest()` al principio, y obtiene el controlador correspondiente `handler : = c.server.Handler` que es el segundo argumento que pasábamos cuando llamamos `ListenAndServe`. Como pasamos `nil`, Go usa su manejador por defecto `handler = DefaultServeMux`. Entonces, ¿qué está haciendo `DefaultServeMux` aquí? Bueno, esta es la variable de enrutador en este momento, se llama a las funciones de controlador de URL específicas . ¿Hemos asignado esto? Sí, lo hicimos. Recuerde que en la primera línea se utilizó `http.HandleFunc("/", sayhelloName)`. Es asi como se utiliza esta función para registrar el estado del router para la ruta "/". Cuando la dirección URL es `/`, el enrutador llama a la función `sayhelloName` . DefaultServeMux llama ServerHTTP para obtener la función de controlador de ruta diferente, y llama `sayhelloName` en este caso. Por último , el servidor escribe los datos y la respuesta a los clientes. Flujo de trabajo detallado: ![](images/3.3.illustrator.png?raw=true) Figura 3.10 Flujo de trabajo de manejar una petición HTTP Creo que ahora debes saber cómo Go se ejecuta servidores web ahora. ## Enlaces - [Indice](preface.md) - Sección anterior: [Armando un servidor web sencillo](03.2.md) - Siguiente sección: [Obteniendo el paquete http](03.4.md)