我試圖在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