net/http 包关键点解析
Go 创建一个 http server
如何创建 http server 服务端
核心
1.保存 path 和 handler 的对应关系
2.请求过来时,查找 path 对应的 handler,然后调用 handler 的 ServeHTTP(w, r)方法
1 | package main |
首先调用 Http.HandleFunc
按顺序做了几件事:
- 调用了 DefaultServerMux 的 HandleFunc
- 调用了 DefaultServerMux 的 Handle
- 往 DefaultServeMux 的 map[string]muxEntry 中增加对应的 handler 和路由规则
其次调用 http.ListenAndServe(“:8001”, nil)
按顺序做了几件事情:
- 实例化 Server
- 调用 Server 的 ListenAndServe()
- 调用 net.Listen(“tcp”, addr)监听端口
- 启动一个 for 循环,在循环体中 Accept 请求
对每个请求实例化一个 Conn,并且开启一个 goroutine 为这个请求进行服务 go c.serve()
读取每个请求的内容 w, err := c.readRequest() - 判断 header 是否为空,如果没有设置 handler(这个例子就没有设置 handler),handler 就设置为 DefaultServeMux 调用 handler 的 ServeHttp
下面就进入到 DefaultServerMux.ServeHttp - 根据 request 选择 handler,并且进入到这个 handler 的 ServeHTTP mux.handler(r).ServeHTTP(w, r)选择 handler: - 判断是否有路由能满足这个 request(循环历 ServerMux 的 muxEntry)
- 如果有路由满足,调用这个路由 handler 的 ServeHttp
- 如果没有路由满足,调用 NotFoundHandler 的 ServeHttp
Go 发送 http 请求
步骤
- 创建 request
- 创建一个 Client 将 request 发送出去,依赖底层 RT 实现,可以是默认的 Transport,也可以是 Mock 的 Transport 或者带缓存的 Transport
1 | func httpDo() { |
1 | //带缓存的传输器 |
问题
net/http 相关类介绍?
1 | Server: 服务器类,接收请求后起协程 处理请求:go srv.newConn(rw).serve(ctx) |
函数 HandlerFunc 如何变成 handler?
设计模式之适配器模式
1 | type Handler interface { |
DefaultServerMux 可以替换吗?
可以,如使用 httprouter 替换默认的 DefaultServerMux 路由
1 | package main |