原文連接golang
Go(Golang.org)是在標準庫中提供HTTP協議支持的系統語言,經過他能夠快速簡單的開發一個web服務器。同時,Go語言爲開發者提供了不少便利。這本篇博客中咱們將列出使用Go開發HTTP 服務器的方式,而後分析下這些不一樣的方法是如何工做,爲何工做的。web
在開始以前,假設你已經知道Go的一些基本語法,明白HTTP的原理,知道什麼是web服務器。而後咱們就能夠開始HTTP 服務器版本的著名的「Hello world」。瀏覽器
首先看到結果,而後再解釋細節這種方法更好一點。建立一個叫http1.go
的文件。而後將下面的代碼複製過去:服務器
package main import ( "io" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello world!") } func main() { http.HandleFunc("/", hello) http.ListenAndServe(":8000", nil) }
在終端執行go run http1.go
,而後再瀏覽器訪問http://localhost:8000。你將會看到Hello world!
顯示在屏幕上。
爲何會這樣?在Go語言裏全部的可運行的包都必須命名爲main
。咱們建立了main和hello兩個函數。
在main函數中,咱們從net/http
包中調用了一個http.HandleFucn
函數來註冊一個處理函數,在本例中是hello函數。這個函數接受兩個參數。第一個是一個字符串,這個將進行路由匹配,在本例中是根路由。第二個函數是一個func (ResponseWriter, Request)
的簽名。正如你所見,咱們的hello函數就是這樣的簽名。下一行中的http.ListenAndServe(":8000", nil)
,表示監聽localhost的8000端口,暫時忽略掉nil。函數
在hello函數中咱們有兩個參數,一個是http.ResponseWriter
類型的。它相似響應流,其實是一個接口類型。第二個是http.Request
類型,相似於HTTP 請求。咱們沒必要使用全部的參數,就想再hello函數中同樣。若是咱們想返回「hello world」,那麼咱們只須要是用http.ResponseWriter,io.WriteString,是一個幫助函數,將會想輸出流寫入數據。ui
下面是一個稍微複雜的例子:spa
package main import ( "io" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello world!") } func main() { mux := http.NewServeMux() mux.HandleFunc("/", hello) http.ListenAndServe(":8000", mux) }
在上面這個例子中,咱們不在在函數http.ListenAndServe
使用nil
了。它被*ServeMux
替代了。你可能會猜這個例子跟我上面的例子是樣的。使用http註冊hanlder 函數模式就是用的ServeMux。
下面是一個更復雜的例子:code
import ( "io" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "Hello world!") } var mux map[string]func(http.ResponseWriter, *http.Request) func main() { server := http.Server{ Addr: ":8000", Handler: &myHandler{}, } mux = make(map[string]func(http.ResponseWriter, *http.Request)) mux["/"] = hello server.ListenAndServe() } type myHandler struct{} func (*myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if h, ok := mux[r.URL.String()]; ok { h(w, r) return } io.WriteString(w, "My server: "+r.URL.String()) }
爲了驗證你的猜測,咱們有作了相同的事情,就是再次在屏幕上輸出Hello world。然而如今咱們沒有定義ServeMux,而是使用了http.Server。這樣你就能知道爲何能夠i是用net/http包運行了服務器了。server