golang http 服务器的接口梳理
Hanlde和HandleFunc以及Handler, HandlerFunc
func Handle(pattern string, handler Handler)// Handle 函数将pattern和对应的handler注册进DefaultServeMuxfunc HandleFunc(pattern string, handler func(ResponseWriter, *Request))// HandleFunc registers the handler function for the given pattern in the DefaultServeMux// Handler// type Handler interface { ServeHTTP(ResponseWriter, *Request)}// HandlerFunc能够将一个普通的处理函数转化为Handlertype HandlerFunc func(ResponseWriter, *Request)
HandleFunc仅接受一个func为参数,相对于简洁些。Handle则需要传入一个带有ServeHTTP的结构体,因此控制逻辑可以灵活些。
Handle的例子package mainimport ( "fmt" "log" "net/http" "sync")type countHandler struct { mu sync.Mutex // guards n n int}func (h *countHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.mu.Lock() defer h.mu.Unlock() h.n++ fmt.Fprintf(w, "count is %d\n", h.n)}func main() { http.Handle("/count", new(countHandler)) log.Fatal(http.ListenAndServe(":8080", nil))}HandleFunc的例子
h1 := func(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "Hello from a HandleFunc #1!\n")}h2 := func(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, "Hello from a HandleFunc #2!\n")}http.HandleFunc("/", h1)http.HandleFunc("/endpoint", h2)log.Fatal(http.ListenAndServe(":8080", nil))
ListenAndServe
// 监听TCP然后调用handler对应的Serve去处理请求。handler默认为nil,则使用DefaultServeMuxfunc ListenAndServe(addr string, handler Handler) error
ServeMux
路由调度器,根据请求url调用handler去处理。实现了Handle,HandleFunc方法。
ServeMux实现了ServeHTTP因此也是一个Handler接口// 新建func NewServeMux() *ServeMux// 方法func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)func (mux *ServeMux) Handle(pattern string, handler Handler)func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)// mux := http.NewServeMux()mux.Handle("/api/", apiHandler{})mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { // The "/" pattern matches everything, so we need to check // that we're at the root here. if req.URL.Path != "/" { http.NotFound(w, req) return } fmt.Fprintf(w, "Welcome to the home page!")})
Server 类型
type Server struct { Addr string // TCP address to listen on, ":http" if empty Handler Handler // handler to invoke, http.DefaultServeMux if nil TLSConfig *tls.Config ReadTimeout time.Duration ReadHeaderTimeout time.Duration WriteTimeout time.Duration IdleTimeout time.Duration MaxHeaderBytes int TLSNextProto map[string]func(*Server, *tls.Conn, Handler) ConnState func(net.Conn, ConnState) ErrorLog *log.Logger // contains filtered or unexported fields}// 方法func (srv *Server) Close() errorfunc (srv *Server) ListenAndServe() errorfunc (srv *Server) ListenAndServeTLS(certFile, keyFile string) errorfunc (srv *Server) RegisterOnShutdown(f func())func (srv *Server) Serve(l net.Listener) errorfunc (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) errorfunc (srv *Server) SetKeepAlivesEnabled(v bool)func (srv *Server) Shutdown(ctx context.Context) error
可以通过Server类型来改变默认的Server配置,如改变监听端口等。
func main(){ http.HandleFunc("/", index) server := &http.Server{ Addr: ":8000", ReadTimeout: 60 * time.Second, WriteTimeout: 60 * time.Second, } server.ListenAndServe()}// 自定义的serverMux对象也可以传到server对象中。func main() { mux := http.NewServeMux() mux.HandleFunc("/", index) server := &http.Server{ Addr: ":8000", ReadTimeout: 60 * time.Second, WriteTimeout: 60 * time.Second, Handler: mux, } server.ListenAndServe()}