在golang缓存网络流?

在golang缓存网络流?,go,network-programming,streaming,nonblocking,Go,Network Programming,Streaming,Nonblocking,我正在尝试为golang中的视频流编写缓存代理 我的问题是,如何在多个连接之间分发大数据块的流式拷贝 或者如何存储缓存并安全快速地访问来自多个goroutine的数据 我尝试了几个选项,包括互斥和通道,但都不起作用。 这里有几个示例可以处理错误 这是简化版: ... var clients []*client func new_client(conn net.Conn) { client := &client{ conn: conn, } clie

我正在尝试为golang中的视频流编写缓存代理

我的问题是,如何在多个连接之间分发大数据块的流式拷贝

或者如何存储缓存并安全快速地访问来自多个goroutine的数据

我尝试了几个选项,包括互斥和通道,但都不起作用。 这里有几个示例可以处理错误

这是简化版:

...
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中进行Wrap调用并没有起到任何作用-存在与下一个示例中的通道相同的延迟,此外go不能保证goroutine的执行顺序

我试着这样修复它:

        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]
        }
    }
}
它有助于阻塞,但速度慢的客户端无法及时读取,从而增加超时返回延迟

我也试过这样的方法:

        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]
        }
    }
}
但在这个版本中,在发送到另一端的通道和接收之间有一些延迟,所以播放器中的视频流开始出现延迟

可能是对go中的一些包的建议,或者是针对此类任务的设计模式


谢谢你的帮助

在通道版本中,慢速客户端也可能增加延迟。因为一个慢客户端可以使其buf_chan满,那么向其buf_chan的写入将被阻止。Wrappper select可以避免:

select {
case client.buf_chan <- buf[0:n]:
default:
//handle slow client ...    
}

谢谢,我监测了buf_chan cannel缓冲区的大小,它在读取后始终为10,我使它缓冲只是为了测试,我认为延迟的问题在其他地方