簡體   English   中英

如何在Go中復用通道輸出

[英]How to multiplex channel output in go

我正在尋找一種解決方案,可以多路傳輸一些通道輸出。

我有一個數據源,該數據源是從io.Reader讀取並發送到單個通道的。 另一方面,我有一個從通道讀取的websocket請求處理程序。 現在,發生了兩個客戶端創建一個websocket連接的情況,這兩個客戶端都從相同的通道讀取數據,但每個客戶端僅獲得部分消息。

代碼示例(簡體):

func (b *Bootloader) ReadLog() (<-chan []byte, error) {
    if b.logCh != nil {
        logrus.Warn("ReadLog called while channel already exists!")
        return b.logCh, nil // This is where we get problems
    }

    b.logCh = make(chan []byte, 0)

    go func() {
        buf := make([]byte, 1024)
        for {
            n, err := b.p.Read(buf)

            if err == nil {
                msg := make([]byte, n)
                copy(msg, buf[:n])
                b.logCh <- msg
            } else {
                break
            }
        }

        close(b.logCh)
        b.logCh = nil
    }()

    return b.logCh, nil
}

現在,當兩次調用ReadLog()時,第二個調用僅返回在第一個調用中創建的通道,這將導致上述問題。

問題是:如何進行適當的復用?

在發送或接收站點上關心多路復用是否更好/更容易/更意識形態?

我應該對接收者隱藏頻道並使用回調嗎?

我現在有點卡住了。 歡迎任何提示。

多路復用非常簡單:創建要多路復用到的通道切片,啟動一個goroutine,該例程從原始通道讀取並將每個消息復制到該切片中的每個通道:

// Really this should be in Bootloader but this is just an example
var consumers []chan []byte

func (b *Bootloader) multiplex() {
    // We'll use a sync.once to make sure we don't start a bunch of these.
    sync.Once(func(){ 
        go func() {
            // Every time a message comes over the channel...
            for v := range b.logCh {
                // Loop over the consumers...
                for _,cons := range consumers {
                    // Send each one the message
                    cons <- v
                }
            }
        }()
    })
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM