鉴于您有两个http.ServeMux
个实例,
并且您希望它们以相同的端口号提供,如下所示:
muxA, muxB http.ServeMux
//initialise muxA
//initialise muxB
combinedMux := combineMux([muxA, muxB])
http.ListenAndServe(":8080", combinedMux)
如上所述,如何编写combinedMux
函数?
...还是有另一种方法来完成同样的事情?
答案 0 :(得分:6)
因为http.ServeMux
也是http.Handler
,您可以轻松地将一个多路复用器嵌套在另一个多路复用器中,即使在相同的端口和相同的主机名上也是如此。这是一个这样做的例子:
rootMux := http.NewServeMux()
subMux := http.NewServeMux()
// This will end up handling /top_path/sub_path
subMux.HandleFunc("/sub_path", myHandleFunc)
// Use the StripPrefix here to make sure the URL has been mapped
// to a path the subMux can read
rootMux.Handle("/top_path/", http.StripPrefix("/top_path", subMux))
http.ListenAndServe(":8000", rootMux)
请注意,如果没有http.StripPrefix()
调用,您需要处理。{
下部多路复用的整条路径。
答案 1 :(得分:3)
SeverMux类型本身就是一个http.Handler,因此您可以轻松地嵌套它们。例如:
mux := NewServeMux()
mux.AddHandler("server1.com:8080/", muxA)
mux.AddHandler("server2.com:8080/", muxB)
我不太确定你的意思是什么"结合"他们。如果你想首先尝试一个处理程序,然后在404的情况下尝试另一个处理程序,你可能会这样做(未经测试):
mux := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rec := httptest.NewRecorder()
rec.Body = &bytes.Buffer{}
muxA.ServeHTTP(rec, r)
if rec.Code == 404 {
muxB.ServeHTTP(w, r)
return
}
for key, val := range rec.HeaderMap {
w.Header().Set(key, val)
}
w.WriteHeader(rec.Code)
rec.Body.WriteTo(w)
})
这显然有一些缺点,比如将整个响应存储在内存中。或者,如果您不介意两次调用处理程序,也可以设置rec.Body = nil
,仅检查rec.Code
并在成功时再次致电muxA.ServeHTTP(w, r)
。但重组应用程序可能更好,这样第一种方法(嵌套的ServerMux)就足够了。