dongzeao5047 2014-12-19 23:49
浏览 41

在golang中缓存网络流?

I'm trying to write caching proxy for video streams in golang.

My question is, how to distribute streaming copy of large chunks of data between multiple connection?

Or how to store (cache) and safely (and fast) access a data from multiple goroutines?

I tried several options, with mutexes and channels, but they didn't work. Here's few samples that worked with errors.

This is simplified version:

...
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
        }
    }
}

Problem with this version is when one client stops reading but doesnt closes connection, call to Write() starts to block. Wrap call to Write() in goroutine (with mutex locks on client) didn't helped - there is same delay as with channels (next example), besides go doesn't guarantees order of execution of goroutines.

I tried to fix it like this:

        for _, client := range clients {
            client.conn.SetWriteDeadline(time.Now().Add(1 * time.Millisecond))
            wn, e := client.conn.Write(buf[0:n])
        }

It helps with blocking, but slow clients can't read in time, increasing timeout - returns delays.

I also tried something like this:

...
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]
        }
    }
}

But in this version - there's some delay between send to channel and receive on the other end, so video stream in player starts getting delays, lags.

Maybe advice for some packages in go, or design patterns for this kind of tasks?

Thanks for any help!

  • 写回答

1条回答 默认 最新

  • dpw50696 2014-12-21 07:46
    关注

    In the channel version, slow client also may increase delay. Because a slow client can make its buf_chan full, then writing to its buf_chan will block. Wrappper select can avoid it:

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

报告相同问题?

悬赏问题

  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 MATLAB中streamslice问题
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 51单片机中C语言怎么做到下面类似的功能的函数(相关搜索:c语言)
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序