-Go- マルチプレクサ(ServeMux)とは
マルチプレクサ、多重器、多重装置、多重化装置、合波器(multiplexer)は、ふたつ以上の入力をひとつの信号として出力する機構である。通信分野では多重通信の入口の装置、電気・電子回路では複数の電気信号をひとつの信号にする回路である。しばしばMUX等と略される。Wikipediaより Goにおけるマルチプレクサ(ServeMux)はHandlerの1つ。(=ServeHTTPを実装している)
code: Go
// Handler Interface
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
if r.RequestURI == "*" {
if r.ProtoAtLeast(1, 1) {
w.Header().Set("Connection", "close")
}
w.WriteHeader(StatusBadRequest)
return
}
h, _ := mux.Handler(r)
h.ServeHTTP(w, r)
}
ServeMuxというハンドラーを利用することで複数のリクエストに対して、対応したハンドラーを振り分けることができる。
code: ServeMuxにパスと対応するhandlerを登録している
func main() {
mux := http.NewServeMux()
mux.Handle("/hoge", hogeHandler)
mux.Handle("/foo", fooHandler)
http.ListenAndServe(":8080", mux)
}
mux.Handleの部分を見てみると...
code: Go
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
mux.mu.Lock()
defer mux.mu.Unlock()
if pattern == "" {
panic("http: invalid pattern")
}
if handler == nil {
panic("http: nil handler")
}
if _, exist := mux.mpattern; exist { panic("http: multiple registrations for " + pattern)
}
if mux.m == nil {
mux.m = make(mapstringmuxEntry) }
e := muxEntry{h: handler, pattern: pattern}
mux.mpattern = e ← ここでスライスにパスとハンドラーを登録してそう! mux.es = appendSorted(mux.es, e)
}
mux.hosts = true
}
}
type muxEntry struct {
h Handler
pattern string
}
mux.m[pattern] = e の部分でスライス にパスとハンドラーを登録してそうだ。
code: これも実はServeMuxを使っている
func main() {
http.Handle("/hoge", hogeHandler)
http.Handle("/foo", fooHandler)
http.ListenAndServe(":8080", nil) // handler to invoke, http.DefaultServeMux if nil
}
http.Handleを見てみると...
code: http.Handleはこうなっている
func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
さらにDefaultServeMuxを見てみると...
code: DefaultServeMuxはこうなっている
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
結局はServeMuxじゃん!
参考サイト: