[英]How to Use ServeMux with ServerConn?
Im creating a Networking API and want people to be able to route requests to specific endpoints using a ServeMux . 我正在创建一个网络API,并希望人们能够使用ServeMux将请求路由到特定的端点。 Instead of using a Server instance, I need to use my own low level ServerConn . 而不是使用Server实例,我需要使用自己的低级ServerConn 。 This is because I am receiving both incoming HTTP requests and plain text data from the same port. 这是因为我从同一端口同时接收传入的HTTP请求和纯文本数据。
The problem, however, is that if I want to forward a request using my ServeMux, I would use it's ServeHTTP method. 但是,问题在于,如果我想使用ServeMux转发请求,我将使用它的ServeHTTP方法。 For this, I need to provide a ResponseWriter, which I don't know how to create an instance of since it is an interface, not a struct. 为此,我需要提供一个ResponseWriter,我不知道如何创建实例,因为它是接口而不是结构。 Should a I create my own ResponseWriter struct? 我应该创建自己的ResponseWriter结构吗? Is there one given by the Golang Standard Library? Golang标准库提供了一个吗? Or is there an alternate solution to this altogether? 还是对此有替代解决方案?
I would avoid doing this altogether if at all possible. 如果可能的话,我将完全避免这样做。 Mixing protocols on the same connection is bound to lead to hard-to-trace bugs, and unexpected behavior. 在同一连接上混合协议必然会导致难以跟踪的错误和意外行为。 If you really want to do it, and have all the http/1.1 mechanisms work correctly, leave as much as possible to the http package. 如果您确实要这样做,并且所有http / 1.1机制都能正常工作,请尽可能多地留给http包。
Since ResponseWriter is an interface, you would implement your own type to satisfy it. 由于ResponseWriter是一个接口,因此您可以实现自己的类型来满足它。 Look at the unexported response
type in the http package for a full example. 查看http包中未导出的response
类型,以获取完整示例。 There's a lot to get right, and using it in combination with a ServerConn (which is documented as "do no use") is probably not a good idea. 有很多事情要做,将其与ServerConn结合使用(记录为“请勿使用”)可能不是一个好主意。
The place to do this at a lower level would be in Accept
inside the Server's net.Listener
. 在这里您可以做到这一点,在一个较低的水平将是Accept
了服务器的内部net.Listener
。 Since you're going to have to parse the start of every request twice, you would need a net.Conn
that can be "rewound" partly. 由于您将不得不两次解析每个请求的开始,因此需要一个可以部分“倒带”的net.Conn
。
Make yourself a net.Listener that checks the start of the stream on a new connection, and if it looks like an http request, return a net.Conn
that replays the first chunk you read off the wire on its first Reads. 使自己成为一个net.Listener,以检查新连接上流的开始,如果它看起来像一个http请求,则返回一个net.Conn
,它在您的第一个net.Conn
上重播从网络读取的第一个块。 Something like: 就像是:
type replayConn struct {
net.Conn
buf []byte
pos int
}
func (c *replayConn) Read(b []byte) (int, error) {
if c.pos < len(c.buf) {
n := copy(b, c.buf[c.pos:])
c.pos += n
return n, nil
}
return c.Conn.Read(b)
}
If the connection isn't http, then send the connection off to your other type of handler, and continue blocking on Accept
. 如果连接不是http,则将连接发送到其他类型的处理程序,并继续在Accept
阻止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.