Go Web伺服器的構造
阿新 • • 發佈:2020-07-12
Go提供了一套完整的Web伺服器標準庫,使得go構建伺服器非常簡單,建立伺服器只需要呼叫ListenAndServe即可。相應的Web函式庫在net/http包中,本文參考《Go Web程式設計》中的內容,介紹伺服器的構造,有興趣的小夥伴可以親自去翻閱這本書。
首先構建兩種最簡單的伺服器:
package main import ( "net/http" ) func main() { http.ListenAndServe("", nil) }
這裡直接是用了http包的ListenAndServe函式,使用者可以自定義Server物件對伺服器進行更多的設定,例如設定超時時間、記錄日誌等操作。
package main import ( "net/http" ) func main() { server := http.Server{ Addr: "127.0.0.1", Handler: nil, } server.ListenAndServe() }
http.Server結構的公開配置如下:
type Server struct { Addr string Handler Handler ReadTimeOut time.Duration WriteTimeOut time.Duration MaxHeaderBytes int TLSConfig *tls.Config ConnState func(net.Conn,ConnState) ErrorLog *log.Logger }
提供HTTPS服務,只需要將監聽函式換為server.ListenAndServeTLS("cert.pem", "key.pem")
處理器和處理函式
上面生成的伺服器沒有寫處理程式,無法處理請求,此時需要新增處理器或處理函式。
例如新增處理器:
package main import ( "fmt" "net/http" ) type MyHandler struct{} func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") } func main() { handler := MyHandler{} server := http.Server{ Addr: "127.0.0.1:8080", Handler: &handler, } server.ListenAndServe() }
如果要使用多個處理器來處理不同的請求:
package main import ( "fmt" "net/http" ) type HelloHandler struct{} func (h *HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") } type WorldHandler struct{} func (h *WorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "World!") } func main() { hello := HelloHandler{} world := WorldHandler{} server := http.Server{ Addr: "127.0.0.1:8080", } http.Handle("/hello", &hello) http.Handle("/world", &world) server.ListenAndServe() }
在上面的定義中,處理器都有一個函式ServeHTTP。在go語言中,一個處理器就是一個擁有ServeHTTP方法的介面。DefaultServeMux多路複用器是ServeMux結構的一個例項,後者也擁有ServeHTTP方法,所以要定義自己的處理器,只需要實現ServeHTTP就行。
上述方式每新增一個請求,就要建立一個handler,會很麻煩。可以使用處理器函式,只需要定義處理函式,而無需建立handler。
package main import ( "fmt" "net/http" ) func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") } func world(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "World!") } func main() { server := http.Server{ Addr: "127.0.0.1:8080", } http.HandleFunc("/hello", hello) http.HandleFunc("/world", world) server.ListenAndServe() }
函式原型為:
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) } func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler) }