简体   繁体   English

如何在ServerConn中使用ServeMux?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM