|
1 |
| -3.4 Llamando al paquete http |
| 1 | +# 3.4 Obteniendo el paquete http |
2 | 2 |
|
3 |
| -En las secciones anteriores , hemos aprendido sobre el flujo de trabajo de la web, y hablamos un poco sobre el paquete http . En esta sección, vamos a aprender dos funciones básicas que estan en el paquete http : Conn , ServeMux . |
| 3 | +En las secciones anteriores, hemos aprendido sobre el flujo de trabajo de la web, y hablamos un poco sobre el paquete `http`. En esta sección, vamos a aprender dos funciones básicas que estan en el paquete `http`: Conn, ServeMux. |
4 | 4 |
|
| 5 | +## goroutine en Conn |
5 | 6 |
|
6 |
| -goroutine en Conn |
7 | 7 | A diferencia de los servidores HTTP normales , Go utiliza goroutine para toda conexion que creó Conn con el fin de lograr una alta concurrencia y rendimiento, por lo que cada caso es independiente.
|
8 | 8 |
|
9 | 9 | Go usa el siguiente código para esperar a nuevas conexiones de clientes .
|
10 | 10 |
|
11 |
| -c , err : = srv.newConn (rw ) |
12 |
| -if ! err = nil { |
13 |
| - continuar |
14 |
| -} |
15 |
| -go c.serve () |
| 11 | + c, err := srv.newConn(rw) |
| 12 | + if err != nil { |
| 13 | + continue |
| 14 | + } |
| 15 | + go c.serve() |
16 | 16 |
|
17 |
| -Como puede ver , se crea una goroutine para cada conexión , y se pasa el controlador que es capaz de leer los datos de solicitud a la goroutine . |
| 17 | +Como puede ver, se crea una goroutine para cada conexión , y se pasa el controlador que es capaz de leer los datos de solicitud a la goroutine . |
18 | 18 |
|
19 |
| - |
20 |
| -ServeMux personalizada |
| 19 | +## ServeMux personalizado |
21 | 20 |
|
22 | 21 | Utilizamos el enrutamiento por defecto en la sección anterior, cuando se habla conn.server , el router pasa los datos de solicitud como back-end al controlador.
|
23 | 22 |
|
24 |
| -El struct del router por defecto : |
25 |
| -type ServeMux struct { |
26 |
| - mu sync.RWMutex //debido a la concurrencia, tenemos que utilizar mutex aquí |
27 |
| - m map[string]muxEntry //routers, cada asignación de cadena a un controlador |
28 |
| -} |
29 |
| -El struct de muxEntry : |
30 |
| -type muxEntry struct { |
31 |
| - explicit bool // exact match or not |
32 |
| - h Handler |
33 |
| -} |
34 |
| -La interfaz de controlador de : |
35 |
| -type Handler interface { |
36 |
| - ServeHTTP(ResponseWriter, *Request) // routing implementer |
37 |
| -} |
| 23 | +El struct del router por defecto: |
| 24 | + |
| 25 | + type ServeMux struct { |
| 26 | + mu sync.RWMutex //debido a la concurrencia, tenemos que utilizar mutex aquí |
| 27 | + m map[string]muxEntry //routers, cada asignación de cadena a un controlador |
| 28 | + } |
| 29 | + |
| 30 | +El struct de muxEntry: |
38 | 31 |
|
39 |
| -Handler es una interfaz , pero la función sayhelloName no implementar su interfaz , por eso podríamos agregarlo como controlador ? Debido a que hay otro tipo HandlerFunc en el paquete http . Llamamos HandlerFunc definir nuestra sayhelloName , así sayhelloName implementa el controladorr al mismo tiempo. que es como llamamos HandlerFunc ( f ) , y la función f es forzado convertido al tipo HandlerFunc . |
| 32 | + type muxEntry struct { |
| 33 | + explicit bool // exact match or not |
| 34 | + h Handler |
| 35 | + } |
| 36 | + |
| 37 | +La interfaz de Handler: |
| 38 | + |
| 39 | + type Handler interface { |
| 40 | + ServeHTTP(ResponseWriter, *Request) // routing implementer |
| 41 | + } |
40 | 42 |
|
41 |
| -type HandlerFunc func(ResponseWriter, *Request) |
| 43 | +`Handler` es una interfaz, pero la función `sayhelloName` no implementar su interfaz , por eso podríamos agregarlo como controlador ? Debido a que hay otro tipo `HandlerFunc` en el paquete `http` . Llamamos `HandlerFunc` definir nuestra `sayhelloName` , así `sayhelloName` implementa el `Handler` al mismo tiempo. que es como llamamos `HandlerFunc(f)`, y la función `f` es forzado convertido al tipo `HandlerFunc`. |
42 | 44 |
|
43 |
| -// ServeHTTP calls f(w, r). |
44 |
| -func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { |
45 |
| - f(w, r) |
46 |
| -} |
| 45 | + type HandlerFunc func(ResponseWriter, *Request) |
47 | 46 |
|
| 47 | + // ServeHTTP calls f(w, r). |
| 48 | + func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { |
| 49 | + f(w, r) |
| 50 | + } |
48 | 51 |
|
49 | 52 | Cómo enrutador llama los controladores después de establecer reglas del router ?
|
50 | 53 |
|
51 |
| -El enrutador llama mux.handler.ServeHTTP ( w , r) cuando recibe solicitudes. En otras palabras, se llama la interfaz ServeHTTP de los controladores . |
| 54 | +El enrutador llama `mux.handler.ServeHTTP(w , r)` cuando recibe solicitudes. En otras palabras, se llama la interfaz `ServeHTTP` de los controladores. |
52 | 55 |
|
53 |
| -Ahora , vamos a ver cómo funciona mux.handler . |
| 56 | +Ahora, vamos a ver cómo funciona `mux.handler`. |
54 | 57 |
|
55 |
| -func (mux *ServeMux) handler(r *Request) Handler { |
56 |
| - mux.mu.RLock() |
57 |
| - defer mux.mu.RUnlock() |
| 58 | + func (mux *ServeMux) handler(r *Request) Handler { |
| 59 | + mux.mu.RLock() |
| 60 | + defer mux.mu.RUnlock() |
58 | 61 |
|
59 |
| - // Host-specific pattern takes precedence over generic ones |
60 |
| - h := mux.match(r.Host + r.URL.Path) |
61 |
| - if h == nil { |
62 |
| - h = mux.match(r.URL.Path) |
63 |
| - } |
64 |
| - if h == nil { |
65 |
| - h = NotFoundHandler() |
| 62 | + // Host-specific pattern takes precedence over generic ones |
| 63 | + h := mux.match(r.Host + r.URL.Path) |
| 64 | + if h == nil { |
| 65 | + h = mux.match(r.URL.Path) |
| 66 | + } |
| 67 | + if h == nil { |
| 68 | + h = NotFoundHandler() |
| 69 | + } |
| 70 | + return h |
66 | 71 | }
|
67 |
| - return h |
68 |
| -} |
| 72 | + |
69 | 73 | El router utiliza la URL como clave para encontrar correspondiente controlador que guarda en un mapa , y llama handler.ServeHTTP para ejecutar funciones para manejar los datos.
|
70 | 74 |
|
71 |
| -Usted debe entender el flujo de trabajo del router , y Go realmente apoya routers personalizados. El segundo argumento de ListenAndServe es para la configuración del router a medida, que es una interfaz de Handler. Por lo tanto , cualquier router implementa controlador de interfaz que se puede utilizar . |
| 75 | +Usted debe entender el flujo de trabajo del router, y Go realmente apoya routers personalizados. El segundo argumento de ListenAndServe es para la configuración del router a medida, que es una interfaz de `Handler`. Por lo tanto , se puede utilizar cualquier router que implemente la interfaz `Handler`. |
72 | 76 |
|
73 | 77 | El siguiente ejemplo muestra cómo implementar un enrutador sencillo.
|
74 | 78 |
|
75 |
| -package main |
| 79 | + package main |
76 | 80 |
|
77 |
| -import ( |
78 |
| - "fmt" |
79 |
| - "net/http" |
80 |
| -) |
| 81 | + import ( |
| 82 | + "fmt" |
| 83 | + "net/http" |
| 84 | + ) |
81 | 85 |
|
82 |
| -type MyMux struct { |
83 |
| -} |
| 86 | + type MyMux struct { |
| 87 | + } |
84 | 88 |
|
85 |
| -func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
86 |
| - if r.URL.Path == "/" { |
87 |
| - sayhelloName(w, r) |
| 89 | + func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
| 90 | + if r.URL.Path == "/" { |
| 91 | + sayhelloName(w, r) |
| 92 | + return |
| 93 | + } |
| 94 | + http.NotFound(w, r) |
88 | 95 | return
|
89 | 96 | }
|
90 |
| - http.NotFound(w, r) |
91 |
| - return |
92 |
| -} |
93 | 97 |
|
94 |
| -func sayhelloName(w http.ResponseWriter, r *http.Request) { |
95 |
| - fmt.Fprintf(w, "Hello myroute!") |
96 |
| -} |
| 98 | + func sayhelloName(w http.ResponseWriter, r *http.Request) { |
| 99 | + fmt.Fprintf(w, "Hello myroute!") |
| 100 | + } |
| 101 | + |
| 102 | + func main() { |
| 103 | + mux := &MyMux{} |
| 104 | + http.ListenAndServe(":9090", mux) |
| 105 | + } |
97 | 106 |
|
98 |
| -func main() { |
99 |
| - mux := &MyMux{} |
100 |
| - http.ListenAndServe(":9090", mux) |
101 |
| -} |
| 107 | +## GO flujo de ejecución del código |
102 | 108 |
|
103 |
| -GO flujo de ejecución del código |
104 | 109 | Vamos a echar un vistazo a la lista de flujo de ejecución en conjunto.
|
105 | 110 |
|
106 |
| --.Se llama http.HandleFunc |
107 |
| - i.- Llame HandleFunc de DefaultServeMux |
108 |
| - ii.- Llame Handle de DefaultServeMux |
109 |
| - iii.- Agregar reglas del router para mapear [cadena ] muxEntry de DefaultServeMux |
110 |
| --. Se llama http.ListenAndServe (": 9090 " , nil ) |
111 |
| - i.- se instancia el servidor |
112 |
| - ii.- Llama ListenAndServe del Servidor |
113 |
| - iii.- Llama net.Listen ( " tcp" , addr ) para escuchar en el puerto . |
114 |
| - iv.- Iniciar un bucle, y aceptar las solicitudes en el cuerpo del bucle. |
115 |
| - v.- Instanciada una Conn se empieza una goroutine para cada solicitud : ir c.serve (). |
116 |
| - vi.- Lee petición de datos : w , err : = c.readRequest (). |
117 |
| - vii.- Comprueba si el controlador está vacío, si está vacíoutiliza DefaultServeMux . |
118 |
| - viii.- Llama al controlador de ServeHTTP |
119 |
| - ix.- Ejecutar código en DefaultServeMux en este caso. |
120 |
| - x.- Elije el controlador URL y ejecutar código del controlador en esta seccion: mux.handler.ServeHTTP ( w , r) |
121 |
| - xi.-Cómo elegir handler: A. Normas de router de verificación para esta URL. B. Llamar ServeHTTP en ese controlador , si es que existe. C. Llamar ServeHTTP de NotFoundHandler lo contrario. |
122 |
| - |
| 111 | +- Se llama http.HandleFunc |
| 112 | + 1. Llame HandleFunc de DefaultServeMux |
| 113 | + 2. Llame Handle de DefaultServeMux |
| 114 | + 3. Agregar reglas del router para mapear [cadena ] muxEntry de DefaultServeMux |
| 115 | +- Se llama http.ListenAndServe (": 9090 " , nil ) |
| 116 | + 1. se instancia el servidor |
| 117 | + 2. Llama ListenAndServe del Servidor |
| 118 | + 3. Llama net.Listen ( " tcp" , addr ) para escuchar en el puerto . |
| 119 | + 4. Iniciar un bucle, y aceptar las solicitudes en el cuerpo del bucle. |
| 120 | + 5. Instanciada una Conn se empieza una goroutine para cada solicitud : ir c.serve (). |
| 121 | + 6. Lee petición de datos : w , err : = c.readRequest (). |
| 122 | + 7. Comprueba si el controlador está vacío, si está vacíoutiliza DefaultServeMux . |
| 123 | + 8. Llama al controlador de ServeHTTP |
| 124 | + 9. Ejecutar código en DefaultServeMux en este caso. |
| 125 | + 10. Elije el controlador URL y ejecutar código del controlador en esta seccion: mux.handler.ServeHTTP ( w , r) |
| 126 | + 11. Cómo elegir handler: |
| 127 | + A. Normas de router de verificación para esta URL. |
| 128 | + B. Llamar ServeHTTP en ese controlador, si es que existe. |
| 129 | + C. Llamar ServeHTTP de NotFoundHandler lo contrario. |
| 130 | + |
| 131 | +## Enlaces |
| 132 | + |
| 133 | +- [Indice](preface.md) |
| 134 | +- Sección anterior: [Como trabaja Go con la web](03.3.md) |
| 135 | +- Siguiente sección: [Resumen](03.5.md) |
0 commit comments