• Go之net/http/server.go中Handler、ServeMux、Server阅读笔记


     

    1. Handler是什么?

    A Handler responds to an HTTP request. 这是源码中的注释,说的就是:一个Handler响应一个HTTP请求。
     
    Handler的定义
    type Handler interface{
        ServerHTTP(ResponseWriter, *Request)
    }

     

    2. Handler的实现者及他们之间的关系

    // 实现一:HandlerFunc
    
    // HandlerFunc是对是用户定义的处理函数的包装,实现了ServeHTTP方法,在方法内执行HandlerFunc对象
    type HandlerFunc func(ResponseWriter, *Request)
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
    }
    
    
    // 实现二:ServeMux
    
    // ServeMux是管理http请求pattern和handler的,实现了ServeHTTP方法,在其内根据请求匹配HandlerFunc,并执行其ServeHTTP方法
    type ServeMux struct {
        mu    sync.RWMutex
        m     map[string]muxEntry
        es    []muxEntry // slice of entries sorted from longest to shortest.
        hosts bool       // whether any patterns contain hostnames
    }
    func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
        h, _ := mux.Handler(r)
        h.ServeHTTP(w, r) // 调用的是HandlerFunc的ServeHTTP
    }
    
    
    // 实现三:serverHandler
    
    // serverHandler是对Server的封装,实现了ServeHTTP方法,并在其内执行ServeMux的ServeHTTP方法
    type serverHandler struct {
        srv *Server
    }
    func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
        handler := sh.srv.Handler
        if handler == nil {
            handler = DefaultServeMux
        }
        ...
        handler.ServeHTTP(rw, req) // 调用的是ServerMux的ServeHTTP
    }
    
    
    // 其他实现
    // ...

    3. ServeMux是干什么的

     ServeMux是一个HTTP请求多路复用器。它根据已注册模式(pattern)列表匹配每个传入请求的URL,并调用与URL最匹配的模式的处理程序(handler)。 
    // ServeMux 是 server multiplexer 简写
    type ServeMux struct {
        mu    sync.RWMutex
        m     map[string]muxEntry
        es    []muxEntry // slice of entries sorted from longest to shortest.
        hosts bool       // whether any patterns contain hostnames
    }
    
    type muxEntry struct {
        h       Handler
        pattern string
    }
    
    // DefaultServeMux是被Serve使用的默认的ServeMux
    var DefaultServeMux = &defaultServeMux
    var defaultServeMux ServeMux
    
    // 服务HTTP
    func (mux *ServeMux) ServeHTTP(W ResponseWriter, r *Request) {
        ...
        h, _ := mux.Handler(r) // 根据请求获取用户定义的handler
        h.ServeHTTP(w, r) // 执行用户定义的handler
    }
    
    // ServeMux处理http请求
    func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
        ...
        return mux.handler(host, r.URL.Path)
    }
    
    // 根据host和path获取Handler
    func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
        mux.mu.RLock()
        defer mux.mu.RUnlock()
        // Host-specific pattern takes precedence over generic ones
        if mux.hosts {
            h, pattern = mux.match(host + path)
        }
        if h == nil {
            h, pattern = mux.match(path)
        }
        if h == nil {
            h, pattern = NotFoundHandler(), ""
        }
        return
    }
    
    
    // 根据path在hanlder map中寻找handler(最长匹配)
    func (mux *ServeMux) match(path string) (h Handler, pattern string) {
        // Check for exact match first.
        v, ok := mux.m[path]
        if ok {
            return v.h, v.pattern
        }
        // Check for longest valid match.  mux.es contains all patterns
        // that end in / sorted from longest to shortest.
        for _, e := range mux.es {
            if strings.HasPrefix(path, e.pattern) {
                return e.h, e.pattern
            }
        }
        return nil, ""
    }
    
    
    // 为pattern注册对应的Handler,如果handler已存在,则panic
    func (mux *ServeMux) Handle(pattern string, handler Handler) {
        mux.mu.Lock()
        defer mux.mu.Unlock()
    
        if pattern == "" {
            panic("http: invalid pattern")
        }
        if handler == nil {
            panic("http: nil handler")
        }
        if _, exist := mux.m[pattern]; exist {
            panic("http: multiple registrations for " + pattern)
        }
    
        if mux.m == nil {
            mux.m = make(map[string]muxEntry)
        }
        e := muxEntry{h: handler, pattern: pattern}
        mux.m[pattern] = e
        if pattern[len(pattern)-1] == '/' {
            mux.es = appendSorted(mux.es, e)
        }
    
        if pattern[0] != '/' {
            mux.hosts = true
        }
    }
    
    // 为pattern注册对应的handler function
    func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        if handler == nil {
            panic("http: nil handler")
        }
        mux.Handle(pattern, HandlerFunc(handler))
    }

    4. 处理函数的注册过程

    http.HandleFunc(pattern, handler)
    
    func HandleFunc(pattern
    string, handler func(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler)
    func (mux
    *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { if handler == nil { panic("http: nil handler") } mux.Handle(pattern, HandlerFunc(handler)) } }

    5. Handle & HandleFunc区别

    HandleFunc内部实际调用的是Handle,HandleFunc将func转化为handler

    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }
    func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }

    6. 从Server到conn再到ServeMux的调用逻辑

     服务启动过程
    http.ListenAndServe(addr, handler) // 这里的handler如果为空,在serverHander执行ServeHTTP内使用DefaultServeMux作为默认的handler
    
    func ListenAndServe(addr string, handler Handler) error {
        server := &Server{Addr: addr, Handler: handler}
        server.ListenAndServe() // 这里的server是在函数内部新创建的
    
        func (srv *Server) ListenAndServe() error {
            ln, err := net.Listen("tcp", addr) // 创建一个监听者
            srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) // 启动服务
    
            func (srv *Server) Serve(l net.Listener) error {
                for { // 死循环处理
                    rw, e := l.Accept() // 接收连接
                    ...
                    c := srv.newConn(rw)
                    c.setState(c.rwc, StateNew) // before Serve can return
                    go c.serve(ctx) // 处理连接
    
                    // Serve a new connection.
                    func (c *conn) serve(ctx context.Context) {
                        for {
                            w, err := c.readRequest(ctx)
                            ...
                            serverHandler{c.server}.ServeHTTP(w, w.req) // Server层服务处理
    
                            func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
                                handler := sh.srv.Handler
                                if handler == nil {
                                    handler = DefaultServeMux
                                }
                                handler.ServeHTTP(rw, req)
    
                                func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { // ServeMux层服务处理
                                    h, _ := mux.Handler(r)
                                    h.ServeHTTP(w, r)
    
                                    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { // HandlerFunc层服务处理
                                        f(w, r) // 至此,会执行用户自定义的请求处理函数
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
  • 相关阅读:
    面向对象的程序设计-继承
    Chrome开发工具之Console
    面向对象的程序设计-原型模式
    面向对象的程序设计-工厂模式、构造函数模式
    面向对象的程序设计-理解对象
    引用类型-Array类型
    引用类型-Object类型
    单体内置对象
    基本包装类型
    引用类型-Function类型
  • 原文地址:https://www.cnblogs.com/zcqkk/p/11584469.html
Copyright © 2020-2023  润新知