本文来源于: https://gobea.cn/blog/detail/15zqpwrq.html
最简略的 http 服务
对于 golang
来说, 创立一个 http 服务是轻而易举的事件, 如下, 咱们创立了一个非常简单的 http 服务, 监听 8899 端口, 只提供一个接口返回 hello world
package main
import (
"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
, 它相当于一个路由注册器, 保留的申请门路pattern
和Handler
对象的 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,而是用来找到路由注册的 handler
func (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 main
import (
"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…