同时将来自流的字节发送到两个目的地

Concurrently send bytes coming from stream to two destinations

将流中的值同时广播到两个网络目标的最佳方式是什么?这是简化的代码:

func main() {
    resp, _ := http.Get("http://origin.com/image.jpeg")

    var buf bytes.Buffer
    // tee, when read, writes to &buf
    respBodyTee := io.TeeReader(resp.Body, &buf)

    sendToClient(respBodyTee)
    uploadeToServer(&buf)
}

一个流不能被读取两次,所以 TeeReader 被用来填充 &bufrespo.Body.

读取的任何内容

但是,函数(sendToClientuploadToServer)将 运行 同步,而我希望它们同时工作。

我想到的解决方案是将一个通道传递给 sendToClient,它将用已发送给客户端的字节填充通道。稍后让 uploadToServer 从同一频道读取。这些方面的内容:

func main() {
    resp, _ := http.Get("http://origin.com/image.jpeg")

    ch := make(chan byte)
    go sendToClient(respBodyTee, ch) // pass 'ch' for writing and run in a goroutine
    uploadeToServer(ch) // will read from 'ch' (synchronous)
}

我是 Go 的新手,不确定上面的方向是否正确。

在您的场景中,最好为 2 个网络调用提供 2 个独立的字节流。如果他们依赖一个源流,当 sendToClient 停顿时 uploadeToServer 将挂起。 channel 不能解决上面的问题,但会引入锁定开销。

你可以尝试io.MultiWriter制作2个独立的字节流

var buf1, buf2 bytes.Buffer
mw := io.MultiWriter(&buf1, &buf2)

if _, err := io.Copy(mw, r.Body); err != nil {
    ...
}
go sendToClient(buf1)
go uploadeToServer(buf2)
...