golang實現一個簡易的http路由及其原理

  1. 前提:實現一個http路由必需要了解net/http包,主要是go/src/net/http/server.go文件
  2. go實現一個web路由主要作三件事:
    • 監聽端口
    • 接收客戶端的請求
    • 爲每一個請求分配對應的handler(對應到php中就是將請求轉發到相應的controller和action)

下面是一個簡單的實現路由的邏輯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)})
}

由此,咱們能夠簡單概括出上文代碼所作的操做:函數

  • 爲不一樣的url規則註冊路由handler  
  • 建立server並監聽端口
  • for循環一直接收request並併發處理

 

PS:  這一期的仍是比較簡單,下一期爭取實現一個真正能知足業務需求的http路由和web url

相關文章
相關標籤/搜索