我试图在golang中为视频流编写缓存代理。在golang中缓存网络流?
我的问题是,如何分配多个连接之间的大块数据的流式副本?
或者如何存储(缓存)并安全(快速)访问多个goroutines中的数据?
我尝试了几个选项,使用互斥锁和通道,但它们不起作用。 这里有几个与错误一起工作的示例。
这被简化版本:
...
var clients []*client
func new_client(conn net.Conn) {
client := &client{
conn: conn,
}
clients = append(clients, client)
}
...
func stream(source io.Reader) {
buf := make([]byte, 32*1024)
for {
n, _ := source.Read(buf)
for _, client := range clients {
wn, e := client.conn.Write(buf[0:n])
// blocks here for all clients if one of clients stops reading
}
}
}
问题的这个版本是当一个客户端停止读取但犯规关闭连接,调用写()开始到框。在goroutine(使用客户端上的互斥锁)中调用Write()函数没有帮助 - 与通道(下一个示例)具有相同的延迟,此外,go不保证goroutines的执行顺序。
我试图修复它是这样的:
for _, client := range clients {
client.conn.SetWriteDeadline(time.Now().Add(1 * time.Millisecond))
wn, e := client.conn.Write(buf[0:n])
}
它有助于阻止,但速度缓慢的客户无法及时阅读,增加超时 - 返回延迟。
我也尝试过这样的事情:
...
var clients []*client
func new_client(conn net.Conn) {
client := &client{
buf_chan: make(chan []byte, 100),
}
clients = append(clients, client)
for {
buf <- client.buf_chan
n, e := client.conn.Write(buf)
}
}
...
func stream(source io.Reader) {
buf := make([]byte, 32*1024)
for {
n, _ := source.Read(buf)
for _, client := range clients {
client.buf_chan <- buf[0:n]
}
}
}
但在这个版本 - 有发送之间有一些延迟到通道和接收在另一端,所以在播放视频流开始变得拖延,滞后。
对于某些软件包可能会提出建议,或者针对这类任务设计模式?
感谢您的帮助!
感谢,我监测buf_chan运河缓冲区的大小,它的百达1(0)读之后,我做到了缓冲只是为了测试,我认为有延迟的问题是其他地方 – user1579228