這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
func main() {http.HandleFunc("/say",say)err := http.ListenAndServe(":8080", nil)if err != nil {log.Fatal(err.Error())}}func say(w http.ResponseWriter, r *http.Request) {//}
上面是一段啟動web服務的代碼通過監聽8080連接埠 並且在啟動錢註冊了say()函數
如在瀏覽器輸入 localhost:8080/say就會預設回調say函數 今天就來分析一下這其中的大致過程
首先在go當中做請求轉寄可以使用系統預設的路由器也可以使用自己定製的路由器但是都必須要去實現Handler介面
type Handler interface {ServeHTTP(ResponseWriter, *Request)}
在路由這一個大量涉及到Handler這個介面不僅僅是自訂路由和預設路由要實現這個介面 甚至文章開頭的例子中say函數在註冊之後都是先強制類型轉換為server.go中的HandleFunc類型 而又由於HandleFunc可以實現了ServeHttp方法 所以就實現了Handler介面 所以每一個註冊的函數其實最後都被當做Handler類型來做處理
下面介紹路由請求分發的大致過程
http.ListenerAndServer(addr,nil) 監聽連接埠 addr 地址 第二個參數設定你自己實現的路由 如果為nil則使用預設的
通過返回的連接埠監聽器監聽addr連接埠 通過l.Aceept 接受串連 go c.serve()為該串連建立一個新的協程去專門處理 因為有for迴圈所以繼續等待接受
func (srv *Server) Serve(l net.Listener) error {defer l.Close()var tempDelay time.Duration // how long to sleep on accept failurefor {rw, e := l.Accept()if e != nil {if ne, ok := e.(net.Error); ok && ne.Temporary() {if tempDelay == 0 {tempDelay = 5 * time.Millisecond} else {tempDelay *= 2}if max := 1 * time.Second; tempDelay > max {tempDelay = max}log.Printf("http: Accept error: %v; retrying in %v", e, tempDelay)time.Sleep(tempDelay)continue}return e}tempDelay = 0c, err := srv.newConn(rw)if err != nil {continue}go c.serve()}}
是個我自己總結的比較關鍵的幾步 先看圖 再解釋
用戶端來請求 然後接收 啟動協程處理 其中serverHandler這一步是server.go內部私人的結構體用來判斷是選擇開發人員自己實現的路由還是預設的路由
無論是哪個路由 都是會調用該路由的ServeHTTP 然後路由在ServeHTTP內部自己處理具體的分發請求
如果是預設的路由則最終會根據路徑 去匹配對應的Handler然後返回 注意這裡的路徑就是一開始註冊的路徑一個路徑對應一個函數也就是一個Handler
將該Handler返回之後則調用該Handler的ServeHTTP 在這個方法內部則是直接調用自己(因為本身就是個函數)然後就是具體外部的方法實現了