同时将来自流的字节发送到两个目的地
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
被用来填充 &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 的新手,不确定上面的方向是否正确。
在您的场景中,最好为 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)
...
将流中的值同时广播到两个网络目标的最佳方式是什么?这是简化的代码:
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 的新手,不确定上面的方向是否正确。
在您的场景中,最好为 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)
...