下面是一個簡單的實現路由的邏輯php
package main import ( "fmt" "net/http" ) func rootGateWay(w http.ResponseWriter, r *http.Request) { println("Welcome to Chris's homepage! ") } func defaultGateWay(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello jingjing") println("Welcome to Chris's homepage! ") } func main() { http.HandleFunc("/", defaultGateWay) http.ListenAndServe(":8080", nil) } //訪問http://host:8080/ 便可看到Hello jingjin
由上面這個例子可知,咱們只執行了兩步就完成了一個簡易的web路由,分別執行了HandleFunc以及ListenAndServe兩個函數。那這兩個函數中又分別執行了什麼操做呢web
先看下面這段源碼:網絡
//用於響應http請求,返回數據 type Handler interface { ServeHTTP(ResponseWriter, *Request) } //HandlerFunc類型實現了Handler接口 type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) } //調用默認ServerMux的HandleFunc方法 func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler) } //把方法handler轉換成HandlerFunc類型,即實現了Handler接口;再執行Handle方法 func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { mux.Handle(pattern, HandlerFunc(handler)) } //路由器註冊一個handler給指定的parttern func (mux *ServeMux) Handle(pattern string, handler Handler) { .... }
不難看出,執行HandleFunc其實就是爲某一規則的請求註冊處理器。併發
下面咱們看看ListenAndServe都幹了什麼,看下面一段源碼:tcp
func ListenAndServe(addr string, handler Handler) error { //初始化一個Server Struct 賦值server的地址和Handler,不過Handler常常性爲空,由於會使 //用DefaultServeMux server := &Server{Addr: addr, Handler: handler} return server.ListenAndServe() } //經過tcp網絡監聽addr地址 func (srv *Server) ListenAndServe() error { addr := srv.Addr if addr == "" { addr = ":http" } ln, err := net.Listen("tcp", addr) if err != nil { return err } //for死循環一直接受http request, 每一個請求開啓一個新的goroutine處理 return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)}) }
由此,咱們能夠簡單概括出上文代碼所作的操做:函數
PS: 這一期的仍是比較簡單,下一期爭取實現一個真正能知足業務需求的http路由和web url