美文网首页
golang HTTP 实例

golang HTTP 实例

作者: 郭青耀 | 来源:发表于2021-10-05 01:33 被阅读0次

    最近温故了一下go web 编程
    看到第一个实例的时候 ,上面写着一段当时没有搞明白的文字

    “main 函数中的两个HTTP函数HandleFunc和ListenAndServe 怎么联系起来的?”

    package main
    
    import (
        "fmt"
        "net/http"
    )
    
    func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello world,%s!", r.URL.Path)
    }
    
    func main() {
        http.HandleFunc("/", handler)
        http.ListenAndServe(":8090", nil)
    }
    

    书中解释了每一行的含义,却没有说明他们的关系。
    这里补充一下当初的疑问:
    http.HandleFunc("/", handler) ,这是个回调函数,浏览器访问的时候,才会调用,即便它写在前面,实际调用 handler函数的时候是在后面执行的。所以要先看后面的函数。
    http.ListenAndServe(":8090", nil)
    看一下它的原型

    // ListenAndServe listens on the TCP network address addr and then calls
    // Serve with handler to handle requests on incoming connections.
    // Accepted connections are configured to enable TCP keep-alives.
    //
    // The handler is typically nil, in which case the DefaultServeMux is used.
    //
    // ListenAndServe always returns a non-nil error.
    func ListenAndServe(addr string, handler Handler) error {
        server := &Server{Addr: addr, Handler: handler}
        return server.ListenAndServe()
    }
    

    这里面注释说handler默认是nil的情况下,handler 的值是DefaultServeMux.

    在看一下:http.HandleFunc的原型:

    // HandleFunc registers the handler function for the given pattern
    // in the DefaultServeMux.
    // The documentation for ServeMux explains how patterns are matched.
    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }
    

    http.HandleFunc操作的对象就是DefaultServeMux.

    并没有结束,因为很多时候注释是不可靠的,我们要看到源码server的默认handler为什么是DefaultServeMux; 我们需要看看 handler的原型:

    type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
    }
    

    handler 是一个接口类型,实现了ServeHTTP函数即可的接口类型,server 的实现在这里,当handler为nil时候,handler被赋值为默认值。

    func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
        handler := sh.srv.Handler
        if handler == nil {
            handler = DefaultServeMux
        }
        if req.RequestURI == "*" && req.Method == "OPTIONS" {
            handler = globalOptionsHandler{}
        }
        handler.ServeHTTP(rw, req)
    }
    
    

    相关文章

      网友评论

          本文标题:golang HTTP 实例

          本文链接:https://www.haomeiwen.com/subject/pqfwnltx.html