Skip to content

Latest commit

 

History

History
85 lines (62 loc) · 4.51 KB

File metadata and controls

85 lines (62 loc) · 4.51 KB

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.

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:

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