1. 我们调用的http.ListenAndServe会生成一个Server对象,这个对象会通过ListenAndServer创建一个监听连接(底层应该就是一个监听socket),然后把这个传递给Serve函数,Serve函数会调用accept开始监听,接受到请求后,会生成一个请求连接(底层应该就是一个连接socket)
2. Server生成请求连接后,会调用其server函数,开协程处理这个函数
3. conn.server处理的过程中,主要会封装出一个ServerHandler来处理这个请求,在处理的时候根据server.Handler(也就是ServerMux)是否为空,看是否使用默认的ServerMux,也就是 DefaultServerMux,然后使用ServerMux来match到这个请求的处理函数,然后进入这个业务处理函数进行处理
一个请求进入到返回响应的流程我们先看看ServeMux这个对象,其定义如下
// ServeMux is an HTTP request multiplexer.
type ServeMux struct {
mu sync.RWMutex
// 保存了 路由到处理函数的映射关系, 比如/ 映射到 index
m map[string]muxEntry
// 这个是用来做无法做精确匹配的情况下,做前缀匹配,比如我们可以让 /mikeyi/miki 映射到/meikeyi/ (在miki不存在的情况下)
es []muxEntry // slice of entries sorted from longest to shortest.
hosts bool // whether any patterns contain hostnames
}
我们看看如下的代码的ServeMux是怎么样的
package main
import (
"fmt"
"net/http"
)
type greeting string
func (g greeting) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, g)
}
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World")
}
func index1(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello index1")
}
func main() {
http.HandleFunc("/", index)
http.HandleFunc("/mikeyi/", index1) # 希望/mikeyi/下面的找不到精确匹配都匹配到/mikeyi下面
http.Handle("/greeting", greeting("Welcome, dj"))
http.Handle("/greeting/mete", greeting("Welcome, mete"))
http.ListenAndServe(":8080", nil)
}
如下是请求到达后的流程图
优秀的设计
等待补充
参考Go 每日一库之 net/http(基础和中间件)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)