从流同时向两个网络目标广播值的最佳方法是什么?这是简化的代码:
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
被用来从&buf
读取的内容填充respo.Body
。
但是,函数(sendToClient
和uploadToServer
)将同步运行,而我希望它们同时进行工作。
我想到的解决方案是将通道传递到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的新手,不确定上面的方向是否正确。
答案 0 :(得分:1)
在您的方案中,最好有2个独立的字节流来进行2个网络调用。如果它们依赖一个源流,则sendToClient
停滞时uploadeToServer
将挂起。通道无法解决上述问题,但会引入锁定开销。
您可以尝试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)
...