
router.Run()的源碼:
然後看到開始調用的是http.ListenAndServe(address, engine), 這個函數是net/http的函數. 然後請求資料就在net/http開始流轉.
是以, gin源碼閱讀系列就是要弄明白以下幾個問題:
request資料是如何流轉的
gin架構到底扮演了什麼角色
請求從gin流入net/http, 最後又是如何回到gin中
gin的context為何能承擔起來複雜的需求
gin的路由算法
gin的中間件是什麼
gin的Engine具體是個什麼東西
net/http的requeset, response都提供了哪些有用的東西
先不使用gin, 直接使用net/http來處理http請求
簡單的說一下http請求是如何建立起來的(需要有基本的網絡基礎,socket程式設計)
在TCP/IP五層模型下, HTTP位于應用層, 需要有傳輸層來承載HTTP協定. 傳輸層比較常見的協定是TCP,UDP, SCTP等. 由于UDP不可靠, SCTP有自己特殊的運用場景, 是以一般情況下HTTP是由TCP協定承載的(可以使用wireshark抓包然後檢視各層協定)
使用TCP協定的話, 就會涉及到TCP是如何建立起來的. 面試中能夠常遇到的名詞三次握手, 四次揮手就是在這裡産生的. 具體的建立流程就不在陳述了, 大概流程就是圖中左半邊
是以說, 要想能夠對用戶端http請求進行回應的話, 就首先需要建立起來TCP連接配接, 也就是socket. 下面要看下net/http是如何建立起來socket?
從圖上可以看出, 不管server代碼如何封裝, 都離不開bind,listen,accept這些函數. 就從上面這個簡單的demo入手檢視源碼.
這段代碼是在注冊一個路由及這個路由的handler到DefaultServeMux中
定義一個函數類型,對一個函數進行轉型成一個類型,然後該類型實作一些方法,進而實作某些接口
可以看到這個路由注冊太過簡單了, 也就給gin, iris, echo等架構留下了擴充的空間, 後面詳細說這個東西
上面路由已經注冊到net/http了, 下面就該如何建立socket了, 以及最後又如何取到已經注冊到的路由, 将正确的響應資訊從handler中取出來傳回給用戶端
1.
<code>_ = http.ListenAndServe(":8080", nil)</code>
2.
這基本是整個過程的代碼了. 基本上是:
ln, err := net.Listen("tcp", addr)做了初試化了socket, bind, listen的操作.
rw, e := l.Accept()進行accept, 等待用戶端進行連接配接
go c.serve(ctx) 啟動新的goroutine來處理本次請求. 同時主goroutine繼續等待用戶端連接配接, 進行高并發操作
h, _ := mux.Handler(r) 擷取注冊的路由, 然後拿到這個路由的handler, 然後将處理結果傳回給用戶端
從這裡也能夠看出來, net/http基本上提供了全套的服務.
從這段函數可以看出來, 比對規則過于簡單, 當能比對到路由的時候就傳回其對應的handler, 當不能比對到時就傳回/. 是以net/http的路由比對無法滿足複雜的需求開發. 是以基本所有的go架構幹的最主要的一件事情就是重寫net/http的route
是以我們直接說gin就是一個httprouter也不過分, 當然gin也提供了其他比較主要的功能, 後面會一一介紹
還有一個go架構要實作的東西是http.ResponseWriter
綜述, net/http基本已經提供http服務的70%的功能, 那些号稱賊快的go架構, 基本上都是提供一些功能, 讓我們能夠更好的處理用戶端發來的請求.
參考連結