本文来源于: https://gobea.cn/blog/detail/15zqpwrq.html

最简略的http服务

对于golang来说,创立一个http服务是轻而易举的事件,如下,咱们创立了一个非常简单的http服务,监听8899端口,只提供一个接口返回hello world

package mainimport (    "fmt"    "net/http")func main() {    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {        fmt.Fprintf(w, "hello world")    })    http.ListenAndServe(":8899", nil)}

当你在游览器输出http://127.0.0.1:8899时,便能看到hello world的输入

http服务

对于golang的http服务,咱们次要了解两个对象,:

  • Handler,它是申请的解决对象,Handler对象须要实现ServeHTTP办法,ServeHTTP执行的是咱们的业务逻辑,个别咱们定义的func(w http.ResponseWriter, r *http.Request)的办法须要通过http.HandlerFunc包装为Handler对象
  • ServeMux,它相当于一个路由注册器,保留的申请门路patternHandler对象的map表,通过pattern找到对应的Handler对象,而后执行Handler对象的ServeHTTP办法

简略的说,http的执行对象是handler,而要成为handler对象.则必须实现ServeHTTP办法,例如HandlerFunc实现了ServeHTTP办法,所以它也是一个handler对象

handler对象

// Handler接口type Handler interface {    ServeHTTP(ResponseWriter, *Request)}// HandlerFunc实现了Handler接口type HandlerFunc func(ResponseWriter, *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {    f(w, r)}

server从路由中找到handler对象,执行handler对象中的ServeHTTP办法,也就是说,要作为路由的Handler对象,须要实现ServeHTTP办法,无关handler如下:

  • handler函数,具备func(w http.ResponseWriter, r *http.Requests)签名的函数,须要通过HandlerFunc函数包装,否则不能作为路由的Handler对象,
  • handler处理函数,通过HandlerFunc构造包装的handler函数,HandlerFunc实现了ServeHTTP接口办法的函数
  • handler对象,实现了Handler接口ServeHTTP办法的构造

注册路由ServeMux

type ServeMux struct {    mu    sync.RWMutex    m     map[string]muxEntry    hosts bool }type muxEntry struct {    explicit bool    h        Handler    pattern  string}// ServeMux也领有ServeHTTP办法,也就说ServeMux实现了Handler接口,即ServeMuX其实也是一个Handler对象,不过ServeMux的ServeHTTP办法不是用来解决request和respone,而是用来找到路由注册的handlerfunc (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {    if r.RequestURI == "*" {        if r.ProtoAtLeast(1, 1) {            w.Header().Set("Connection", "close")        }        w.WriteHeader(StatusBadRequest)        return    }    h, _ := mux.Handler(r)    h.ServeHTTP(w, r)}

如上,ServeMux.m保留了路由规定pattern以及对应的Handler解决对象,另外ServeMux也领有ServeHTTP办法,也就说ServeMux实现了Handler接口,即ServeMuX其实也是一个Handler对象,不过ServeMux的ServeHTTP办法不是用来解决request和respone,而是用来找到路由注册的handler

package mainimport (    "fmt"    "net/http")func main() {    mux := http.NewServeMux()    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {        fmt.Fprintf(w, "hello world")    })    mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {        fmt.Fprintf(w, "hello world")    })    http.ListenAndServe(":8899", mux)}

Server

http.ListenAndServe(":8899",mux)// 等价于serv := &http.Server{        Addr:    ":8899",        Handler: mux,    }serv.ListenAndServe()

http.ListenAndServe源码如下:

func ListenAndServe(addr string, handler Handler) error {    server := &Server{Addr: addr, Handler: handler}    return server.ListenAndServe()}

起源

  • https://gobea.cn/blog/detail/...

参考

  • https://www.jianshu.com/p/be3...