2014-12-19 68 views
1

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

但在這個版本 - 有發送之間有一些延遲到通道和接收在另一端,所以在播放視頻流開始變得拖延,滯後。

對於某些軟件包可能會提出建議,或者針對這類任務設計模式?

感謝您的幫助!

回答

0

在頻道版本中,慢速客戶端也可能增加延遲。由於緩慢的客戶端可能會使其buf_chan變滿,因此寫入其buf_chan將會被阻止。 Wrappper選擇能避免它:

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

感謝,我監測buf_chan運河緩衝區的大小,它的百達1(0)讀之後,我做到了緩衝只是爲了測試,我認爲有延遲的問題是其他地方 – user1579228