【问题标题】:Go: How to combine two (or more) http.ServeMux?Go:如何组合两个(或多个)http.ServeMux?
【发布时间】:2014-07-04 19:16:00
【问题描述】:

假设您有两个 http.ServeMux 实例, 并且您希望它们在相同的端口号上提供服务,如下所示:

    muxA, muxB http.ServeMux
    //initialise muxA
    //initialise muxB
    combinedMux := combineMux([muxA, muxB])
    http.ListenAndServe(":8080", combinedMux)

如上所述,如何编写combinedMux 函数?

...或者有其他方法可以完成同样的事情吗?

【问题讨论】:

  • 你能提供一些关于这两个 ServeMux 做什么的信息吗?它们可以一个接一个地运行吗?为什么使用两个多路复用器而不是 1 个具有多个处理程序?
  • @tony: 2 个处理程序也可以工作。一个由martini 提供,另一个由socket.io 提供。 Martini 结构实现了http.HandlerFunc 的接口,而SocketIOServer 扩展了*http.ServeMux - 基本上我想要做的是从同一个服务器和端口提供服务。

标签: http go servemux


【解决方案1】:

因为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() 调用,您将需要处理 下部多路复用器中的整个路径。

【讨论】:

  • 如果 root mux 是 Gorilla Mux,你能做同样的事情吗? rootMux := mux.NewRouter()
  • 很好的答案。非常适合混合微服务
【解决方案2】:

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)就足够了。

【讨论】:

  • 对于您发布的第一个代码块,如果 muxA 和 muxB 都在同一个服务器和端口上侦听,但它们处理的路径不同,这会起作用吗?
猜你喜欢
  • 1970-01-01
  • 2011-02-16
  • 2023-02-26
  • 2017-07-24
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
相关资源
最近更新 更多