1. 程式人生 > >golang學習之negroni對於第三方中介軟體的使用分析

golang學習之negroni對於第三方中介軟體的使用分析

 negroni本身是一箇中間件,不過它也提供了拓展,以幫助我們更簡單地實現自己想要的功能的中介軟體。那麼,我們究竟該如何實現中介軟體,才能能夠封裝到negroni中,從而通過negroni來呼叫呢?可以通過一個簡單的例子分析:

package main
import (
"fmt"
"net/http"

"github.com/urfave/negroni"
"github.com/phyber/negroni-gzip/gzip"
)

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!"
) }) n := negroni.Classic() //建立一個negroni n.Use(gzip.Gzip(gzip.DefaultCompression)) n.UseHandler(mux) n.Run(":3000") }

  我們從negroni建立之後開始分析。n.UseHandler(mux)函式:

n.UseHandler(mux)
    +func (n *Negroni) UseHandler(handler http.Handler)
        |n.Use(Wrap(handler))
        +func Wrap(handler http.Handler
) Handler |return HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) +func (n *Negroni) Use(handler Handler) |n.handlers = append(n.handlers, handler) |n.middleware = build(n.handlers) +func build(handlers []Handler
) middleware |return middleware{handlers[0], &next}

  呼叫n.UseHandler(mux)函式的過程中,同樣也呼叫了n.Use()函式。說明negroni對於第三方中介軟體的使用是從n.UseHandler開始的。
  接下來,一起來分析追蹤過程中遇到的函式:

1. UseHandler

  該函式返回將handler傳遞給Wrap()函式

func (n *Negroni) UseHandler(handler http.Handler) {
    n.Use(Wrap(handler))
}

2. Wrap

  該函式對handler進行封裝,程式設計固定format的handler。

func Wrap(handler http.Handler) Handler {
    return HandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
        handler.ServeHTTP(rw, r)
        next(rw, r)
    })
}

3. Use

  該函式則將handler新增到Negroni結構體中。其中,midlleware是一個連結串列。

func (n *Negroni) Use(handler Handler) {
    if handler == nil {
        panic("handler cannot be nil")
    }

    n.handlers = append(n.handlers, handler)
    n.middleware = build(n.handlers)
}

+-----------------------------------------+
type Negroni struct {
    middleware middleware
    handlers   []Handler
}

type middleware struct {
    handler Handler
    next    *middleware
}

4. build

  如果你瞭解C/C++,這個函式很好理解。它僅僅是一個迭代函式,實現了middleware連結串列的構建。

func build(handlers []Handler) middleware {
    var next middleware

    if len(handlers) == 0 {
        return voidMiddleware()
    } else if len(handlers) > 1 {
        next = build(handlers[1:])
    } else {
        next = voidMiddleware()
    }

    return middleware{handlers[0], &next}
}

5. 對ServerHTTP的處理

  同時,我們也要清楚Handler是一個介面,一個Handler物件必須實現Handler介面。Handler介面定義如下:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

  negroni對ServeHTTP做了哪些處理呢?通過以下三個函式可以瞭解:

//函式型別,使用HandleFunc會呼叫
//func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)的實現
type HandlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)

//呼叫函式實現
func (h HandlerFunc) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
    h(rw, r, next)
}

//實現ServerHTTP的封裝
func (m middleware) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
    m.handler.ServeHTTP(rw, r, m.next.ServeHTTP)
}

接下來,我們追蹤n.Run(“:3000”)函式:

n.Run(":3000")
    +func (n *Negroni) Run(addr ...string)
    |finalAddr := detectAddress(addr...)
        +func detectAddress(addr ...string) string
    |l.Fatal(http.ListenAndServe(finalAddr, n))
        +func ListenAndServe(addr string, handler Handler) error
        |......

  negroni.Run解析address後,最終呼叫了http.ListenAndServe來實現伺服器。這一步,才最終完成了伺服器的搭建;所有的handler都交付給了http.ListenAndServe去實現。


  關於negroni對於第三方中介軟體的使用就分析到這裡了。

相關推薦

golang學習negroni對於第三方中介軟體的使用分析

 negroni本身是一箇中間件,不過它也提供了拓展,以幫助我們更簡單地實現自己想要的功能的中介軟體。那麼,我們究竟該如何實現中介軟體,才能能夠封裝到negroni中,從而通過negroni來呼叫呢?可以通過一個簡單的例子分析: package main

golang 學習語言切片Slice Range範圍 MAP 遞迴函式

Go 語言切片是對陣列的抽象。 Go 陣列的長度不可改變,在特定場景中這樣的集合就不太適用,Go中提供了一種靈活,功能強悍的內建型別切片(“動態陣列”),與陣列相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。 定義一個未指定大小的切片

golangWeb框架---github.com/gin-gonic/gin學習七(重定向、中介軟體Goroutines、http自定義配置)

重定向 package main import ( "github.com/gin-gonic/gin" "net/http" ) func main() { router := gin.Default() router.GET("/raw",

Golang學習Goroutines和 channel

Goroutines 在Go語言中,每一個併發的執行單元叫作一個goroutine,可以簡單地把goroutine類比作一個執行緒,本質上是一個協程。但它與協程有倆點不同: goroutinue可以實現並行,也就是說,多個協程可以在多個處理器同時跑。而協程同一

GOLANG 學習陣列

陣列是值型別 [10]int和[20]int是不同型別 呼叫func f(arr [5]int)會拷貝陣列 在go語言中一般不直接使用陣列 申明一個數組 // variable_name-變數名稱

golang學習net/http 原始碼分析

2018年11月15日 18:30:57 焰絕 閱讀數:4 個人分類: 服務計算

【Java進階面試系列五】訊息中介軟體叢集崩潰,如何保證百萬生產資料不丟失?【石杉的架構筆記】

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100) 週一至週五早8點半!精品技術文章準時送上! “上一篇講訊息中介軟體的文章《扎心!線上服務宕機時,如何保證資料100%不丟失?》,初步給大家介紹了一個在生產環境中可能遇到的問題,就是你的消費者服務可能會宕機,一旦宕機,你就需要考慮是否會導致

Golang學習從命令列讀取config配置檔案

Golang學習筆記之從命令列讀取配置檔案 注:本文為個人學習筆記,如果你看到本文有收穫請給予點贊支援,如果發現錯誤,請告知,謝謝! 應用場景 很多時候,我們都是講伺服器環境配置引數在程式碼中寫死,然後隨著程式碼打不同環境的包檔案 ,那麼如何才能動態載入我們所需要的配置檔案呢?這個時候,是

Golang學習net包介紹

       與大多數語言一樣,Go的標準庫很全,因為Go的出現本來就是為了網路通訊的高併發實現,所以其相關的網路庫封裝得更簡潔,更Readable。        這裡來大致介紹幾個網路庫,掌握了學習方法,那麼只要裡面有那個功能,你就能找到並快讀查閱原始碼

Golang學習在專案中遇到的幾個常用的方法

1、TempFile        TempFile 在 dir 目錄中建立一個以 prefix 為字首的臨時檔案,並將其以讀        寫模式開啟。返回建立的檔案物件和遇到的錯誤。        如果 dir 為空,則在預設的臨時目錄中建立檔案(

golang學習安裝環境

安裝: 1. 官網安裝最新的golang安裝包 我的是win7下載的是go1.4.2.windows-amd64 配置環境變數    export GOROOT=$HOME/go     export PATH=$PATH:$GOROOT/bin 再配置GOPATH,路

Golang學習GOROOT、PATH、GOPATH及go get

1. GOROOT GOPATH 及 PATH 設定 a.新增系統變數GOROOT:安裝完Go第一件事就是設定GOROOT。例如我的Go安裝在C:\Go目錄,則要設定 GOROOT = C:\Go b.修改環境變數PATH:將%GOROOT%\bin加到環境變數PATH

Django元件使用者認證和中介軟體

使用者認證元件 功能:用session記錄登入驗證狀態 前提:使用者表 django自帶的auth_user 建立超級使用者python manage.py createsuperuser API 如下 一、 auth模組 1: from django.contrib import

golang學習指標、記憶體分配

1 func pointer_test() { 2 //空指標,輸出為nil 3 var p *int 4 fmt.Printf("p: %v\n", p) 5 //指向區域性變數,變數值初始為0 6 var i int 7 p = &i

【React全家桶入門十三】Redux中介軟體與非同步action

在上一篇中我們瞭解到,更新Redux中狀態的流程是這樣的:action -> reducer -> new state。 文中也講到,action是一個普通的javascript物件、reducer是一個普通的方法,在reducer中根據當前的st

【轉】Golang學習同一個package中函式互相呼叫的問題

問題程式碼如下 a.go: package main func main(){ Test() } b.go: package main import "fmt" func Test(){ fmt.Println("Hello World!") } 這

Golang 學習路一:開發環境搭建

Golang 學習:開發環境搭建 一、下載適合本機的Golang版本 注意對應好自己PC 的system. Windows 直接下載對應的msi安裝即可,Linux注意發行版本。 本文L

效能測試中介軟體分析與調優

   目前招聘效能測試工程師,都要求要了解中介軟體,中介軟體也是效能測試工程師必須要掌握的一大節點,所以有必要對中介軟體的相關含義及架構有一定的瞭解,那麼問題來了,中介軟體到底是什麼?在整個系統中承擔一個什麼樣的角色? 中介軟體定義    中介軟體是一類連線

Golang學習標準庫io/ioutil,讀取檔案,生成臨時目錄/檔案

1.讀取目錄 list, err := ioutil.ReadDir("DIR")//要讀取的目錄地址DIR,得到列表 if err != nil { fmt.Println("read dir error") return } for _,

Golang 學習路九:介面(Interface)

Golang學習之路:介面(interface) 一、前言   Go 語言和傳統的OO語言概念思想上不同,它在語法上不支援類與整合的概念。但是為了實現類似於C++等語言中多型行為,Go語言引入了interface型別,實現了類似於多型的功能。注意inte