婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 深入理解Go語言中的Dispatcher

深入理解Go語言中的Dispatcher

熱門標簽:釘釘有地圖標注功能嗎 鄭州亮點科技用的什么外呼系統 黃岡人工智能電銷機器人哪個好 惠州電銷防封電話卡 阿里云ai電話機器人 建造者2地圖標注 浙江高頻外呼系統多少錢一個月 濱州自動電銷機器人排名 汕頭小型外呼系統

介紹

Go使用goroutines來處理connection的讀寫事件,不會阻塞:

c, err := srv.newConn(rw)
  if err != nil {
    continue
  }
  go c.serve()

c即為創建的connection,保存了該次請求的信息,然后再傳遞到對應的handler,handler就可以讀取到請求的header信息,保證了請求之間獨立。

Go中的ServeMux

上面代碼中提到了c(這個c就是connection).serve()方法。其實內部是調用了http包默認的路由器,通過路由器把本次請求的信息傳遞到了后端的處理函數。

默認路由器ServeMux,結構如下:

type ServeMux struct {
 mu sync.RWMutex  //鎖,由于請求涉及到并發處理,因此這里需要一個鎖機制
 m map[string]muxEntry // 路由規則,一個string對應一個mux實體,這里的string就是注冊的路由表達式
 hosts bool // 是否在任意的規則中帶有host信息
}

下面看一下muxEntry:

type muxEntry struct {
 explicit bool  // 是否精確匹配
 h    Handler // 這個路由表達式對應哪個handler
 pattern string //匹配字符串
}

接著看一下Handler的定義:

type Handler interface {
 ServeHTTP(ResponseWriter, *Request) // 路由實現器
}

Handler是一個接口,但是前一小節中的sayhelloName函數并沒有實現ServeHTTP這個接口,仍然能添加到路由表中,原因就是http包里還有一個HandlerFunc,我們定義的函數sayhelloName就是這個HandlerFunc調用的結果,而這個類型默認實現了ServeHTTP這個接口,即我們調用了HandlerFunc(f) ,強制類型轉換f成為HandlerFunc類型,這樣f就擁有了ServeHTTP方法。

type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
  f(w, r)
}

我們看一下HandlerFunc的官方注解:

HandlerFunc類型是一個適配器,允許使用普通的函數作為HTTP處理程序。如果f是具有適當簽名的函數,HandlerFunc(f)是調用f的Handler。

適當的簽名,由于作者水平也不深厚(畢竟我本命語言是java),猜一下指的應該是函數的參數以及返回值,也就是說:如果函數的參數是兩個,分別是ResponseWriter和一個指向Request的指針,并且返回值為void類型的函數,可以強轉為HandlerFunc,而最終調用的f中的Handler接口的方法也就是ServeHttp。

路由器里面存儲好了相應的路由規則之后,那么具體的請求又是怎么分發的呢?請看下面的代碼,默認的路由器實現了ServeHTTP:

func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
 if r.RequestURI == "*" {
 w.Header().Set("Connection", "close")
 w.WriteHeader(StatusBadRequest)
 return
 }
 h, _ := mux.Handler(r)
 h.ServeHTTP(w, r)
}

如上所示路由器接收到請求之后,如果是*那么關閉鏈接,不然調用mux.Handler(r)返回對應設置路由的處理Handler,然后執行h.ServeHTTP(w, r) 。看一下ServeMUX.Handler(*request)的官方文檔:

Handler返回用于給定請求的處理程序,請咨詢r.Methodr.Hostr.URL.Path。它總是返回一個非nil處理程序。如果路徑不是其規范形式,處理程序將是重定向到規范路徑的內部生成的處理程序。

Handler還返回與請求匹配的注冊模式,或者在內部生成的重定向的情況下,返回在跟隨重定向之后匹配的模式。

如果沒有適用于請求的注冊處理程序,則Handler返回“未找到頁面”處理程序和空模式。

說白了,根據request的method、host和請求的URL的路徑返回一個處理程序,這個處理程序就是我們說過的Handler,再看看Handler接口的方法,我們就知道了,最終會跑到我們sayhelloName里面~。我們看看ServeMux.Handler(*request)的實現:

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
 if r.Method != "CONNECT" {
 if p := cleanPath(r.URL.Path); p != r.URL.Path {
  _, pattern = mux.handler(r.Host, p)
  return RedirectHandler(p, StatusMovedPermanently), pattern
 }
 }  
 return mux.handler(r.Host, r.URL.Path)
}
func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
 mux.mu.RLock()
 defer mux.mu.RUnlock()
 // Host-specific pattern takes precedence over generic ones
 if mux.hosts {
 h, pattern = mux.match(host + path)
 }
 if h == nil {
 h, pattern = mux.match(path)
 }
 if h == nil {
 h, pattern = NotFoundHandler(), ""
 }
 return
}

為了不讓讀者懵逼,我們還是看一下match方法,這是個私有方法,循環迭代了mux中的map:

func (mux *ServeMux) match(path string) (h Handler, pattern string) {
 var n = 0
 for k, v := range mux.m {
 if !pathMatch(k, path) {
  continue
 }
 if h == nil || len(k) > n {
  n = len(k)
  h = v.h
  pattern = v.pattern
 }
 }
 return
}

匹配到之后返回存儲的handler,調用這個handler的ServeHTTP接口就可以執行到相應的函數了。

Go其實支持外部實現的路由器 ListenAndServe的第二個參數就是用以配置外部路由器的,它是一個Handler接口,即外部路由器只要實現了Handler接口就可以,我們可以在自己實現的路由器的ServeHTTP里面實現自定義路由功能。

我們實現一個簡易路由器:

package main
import (
 "fmt"
 "net/http"
)
type MyMux struct {}
func (p *MyMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 if r.URL.Path == "/" {
 sayhelloName(w, r)
 return
 }
 http.NotFound(w, r)
 return
}
func sayhelloName(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintf(w, "Hello myroute!")
}
func main() {
 mux := MyMux{}
 http.ListenAndServe(":9090", mux)
}

通過對http包的分析之后,現在讓我們來梳理一下整個的代碼執行過程:

1、首先調用Http.HandleFunc,按順序做了幾件事:

  • 調用了DefaultServeMux的HandleFunc
  • 調用了DefaultServeMux的Handle
  • 往DefaultServeMux的map[string]muxEntry中增加對應的handler和路由規則

2、其次調用http.ListenAndServe(“:9090”, nil) ,按順序做了幾件事情:

  • 實例化Server
  • 調用Server的ListenAndServe()
  • 調用net.Listen(“tcp”, addr)監聽端口
  • 啟動一個for循環,在循環體中Accept請求
  • 對每個請求實例化一個Conn,并且開啟一個goroutine為這個請求進行服務go c.serve()
  • 讀取每個請求的內容w, err := c.readRequest()
  • 判斷handler是否為空,如果沒有設置handler(這個例子就沒有設置handler),handler就設置為DefaultServeMux
  • 調用handler的ServeHttp
  • 在這個例子中,下面就進入到DefaultServeMux.ServeHttp
  • 根據request選擇handler,并且進入到這個handler的ServeHTTP,mux.handler(r).ServeHTTP(w, r)
  • 選擇handler:
  • 判斷是否有路由能滿足這個request(循環遍歷ServerMux的muxEntry)
  • 如果有路由滿足,調用這個路由handler的ServeHttp
  • 如果沒有路由滿足,調用NotFoundHandler的ServeHttp

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

標簽:泰安 瀘州 阿壩 東營 昭通 駐馬店 晉中 滄州

巨人網絡通訊聲明:本文標題《深入理解Go語言中的Dispatcher》,本文關鍵詞  深入,理解,語言,中的,Dispatcher,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《深入理解Go語言中的Dispatcher》相關的同類信息!
  • 本頁收集關于深入理解Go語言中的Dispatcher的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产精品久久久久久妇女6080| 欧美在线观看视频一区二区三区| 亚洲图片欧美视频| 亚洲一区二区高清| 久国产精品韩国三级视频| 国产呦萝稀缺另类资源| 91在线精品秘密一区二区| 欧美亚洲高清一区二区三区不卡| 欧美精品在欧美一区二区少妇| 26uuu国产在线精品一区二区| 中文字幕在线一区| 亚洲国产wwwccc36天堂| 久久福利资源站| 91美女蜜桃在线| 精品久久久影院| 一区二区三区四区乱视频| 久久国产精品99久久人人澡| 99视频一区二区| 日韩一区二区三区精品视频| 中文字幕第一页久久| 日日夜夜精品视频天天综合网| 国产精品中文字幕日韩精品| 亚洲欧美日韩国产另类专区| 色综合天天性综合| 国产资源精品在线观看| 国产一区在线不卡| 中文字幕精品在线不卡| 国产精品区一区二区三区| 日韩和欧美一区二区三区| 丝袜美腿高跟呻吟高潮一区| 成人毛片老司机大片| 93久久精品日日躁夜夜躁欧美| 3d动漫精品啪啪1区2区免费| 久久久久久夜精品精品免费| 国产成人夜色高潮福利影视| 欧美一区二区视频免费观看| 国产日韩欧美激情| 水野朝阳av一区二区三区| 国产一区在线看| 日韩欧美视频一区| 亚洲精品欧美激情| 日本一区二区三级电影在线观看 | 亚洲色图一区二区三区| 激情综合网av| 欧美日韩一区二区三区高清| 欧美一区二区三区免费| 一区在线中文字幕| 日韩欧美成人激情| 亚洲综合久久久| 成人一级视频在线观看| 欧美日韩极品在线观看一区| 国产精品三级av| 亚洲亚洲人成综合网络| 老司机一区二区| 欧美日韩国产中文| 亚洲乱码国产乱码精品精可以看 | 91久久精品日日躁夜夜躁欧美| 精品免费国产一区二区三区四区| 国产欧美日韩另类视频免费观看| 亚洲超碰97人人做人人爱| 国产一区二区免费看| 欧美日韩亚洲另类| 在线一区二区三区做爰视频网站| 色素色在线综合| 国产亚洲欧美激情| 丝袜亚洲精品中文字幕一区| 色综合天天综合网国产成人综合天 | 91久久线看在观草草青青| 日韩一区二区免费在线电影| 夜夜精品浪潮av一区二区三区| 国产在线国偷精品免费看| 欧美日韩aaa| 一本高清dvd不卡在线观看 | 夜夜嗨av一区二区三区网页| 欧美三级乱人伦电影| 国产精品午夜春色av| proumb性欧美在线观看| 久久蜜桃一区二区| 成人丝袜视频网| 中文字幕国产一区| 欧洲激情一区二区| 日本视频一区二区三区| 国产精品影视天天线| 尤物av一区二区| 色噜噜狠狠色综合中国| 亚洲黄色尤物视频| 色综合天天综合在线视频| 亚洲欧美怡红院| 91麻豆视频网站| 亚洲人成在线播放网站岛国| 国产在线看一区| 欧美一二三区在线| 久久久久97国产精华液好用吗| 国产一区二区三区在线观看免费视频 | 欧美怡红院视频| 欧美一级二级三级蜜桃| 九九在线精品视频| 日韩丝袜情趣美女图片| 亚洲成人精品影院| 欧美精品久久天天躁| 奇米在线7777在线精品| 精品日韩在线观看| 成人综合激情网| 亚洲精品日日夜夜| 欧美精品777| 国产成人免费9x9x人网站视频| 日韩亚洲欧美综合| 五月婷婷久久丁香| 国产在线视频精品一区| 中文字幕中文在线不卡住| 成人听书哪个软件好| 日韩毛片视频在线看| 欧洲精品中文字幕| 久色婷婷小香蕉久久| 这里是久久伊人| 久久99国产精品久久| 国产欧美综合色| 美日韩黄色大片| 国产精品久久久久久久久免费樱桃| 久久狠狠亚洲综合| 亚洲黄色性网站| 欧美大片国产精品| 国产精品一区二区久激情瑜伽| 中文字幕在线不卡国产视频| 丁香六月综合激情| 亚洲国产成人av网| 日韩视频一区二区三区| 不卡电影一区二区三区| 久久精品亚洲精品国产欧美kt∨ | 成人自拍视频在线| 日本亚洲三级在线| 亚洲女女做受ⅹxx高潮| 精品国产一区二区三区久久久蜜月 | 日本怡春院一区二区| 欧美一级爆毛片| av在线播放一区二区三区| 婷婷国产v国产偷v亚洲高清| 欧美精品一二三| 一本色道久久综合亚洲aⅴ蜜桃 | 欧美va天堂va视频va在线| 91丝袜国产在线播放| 亚洲图片一区二区| 椎名由奈av一区二区三区| 欧美裸体bbwbbwbbw| 国产99久久久精品| 久久色.com| 成人免费黄色大片| 精品在线亚洲视频| 欧美日韩成人综合天天影院| 欧美精品vⅰdeose4hd| 99免费精品在线观看| 狠狠色狠狠色综合系列| 首页国产欧美久久| 欧美性大战久久久久久久| 成人综合在线网站| 亚欧色一区w666天堂| 亚洲男女一区二区三区| 国产精品久久久久久久久晋中| 精品少妇一区二区三区视频免付费 | 蜜桃视频一区二区| 亚洲成在线观看| 国产精品久久久久久久久动漫 | 久久久午夜精品理论片中文字幕| 亚洲图片你懂的| 中文字幕欧美国产| 欧美亚州韩日在线看免费版国语版| 成人影视亚洲图片在线| 亚洲成人777| 国产嫩草影院久久久久| 久久九九国产精品| 在线不卡一区二区| 欧美一区二区三区四区在线观看| 国产盗摄女厕一区二区三区| 激情综合色综合久久综合| 亚洲视频一二三区| 亚洲色图欧洲色图婷婷| 亚洲精品美国一| 亚洲成a人片在线不卡一二三区| 亚洲精品一区二区三区99| 久久久久久影视| 日韩片之四级片| 精品对白一区国产伦| 777欧美精品| 在线综合视频播放| 日本福利一区二区| 亚洲欧美日韩一区二区| 亚洲精品国产高清久久伦理二区| 国产午夜精品一区二区三区嫩草 | 亚洲国产成人午夜在线一区| 中文字幕亚洲区| 精品国产伦理网| 日韩欧美亚洲另类制服综合在线| 日韩一级黄色片| 国产精品视频麻豆| 亚洲图片有声小说| 国产日韩欧美综合在线| 亚洲精品国产成人久久av盗摄| 国产色综合久久| 亚洲国产婷婷综合在线精品| 国产精品私人自拍|