2017-12-01 6 views
0

私はいくつかのチャネル出力をgoで多重化するソリューションを探しています。goでチャネル出力を多重化する方法

私は、単一のチャンネルに送信するio.Readerからの読み取りであるデータソースを持っています。反対側で私はチャネルから読み取るwebsocket要求ハンドラがあります。今度は、2つのクライアントが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()が2回呼び出されたときに、2番目の呼び出しは、ちょうど前述した問題につながる最初の呼び出しで作成されたチャネルを返します。

質問はどのように適切な多重化を行うのですか?

送信サイトまたは受信サイトで多重化を気にするのは、より良い/より簡単なことですか。

チャネルを受信者から隠し、コールバックを使用する必要がありますか?

私はちょっと迷っています。ヒントは大歓迎です。

+1

何」:あなたは、マルチプレックス元のチャネルおよびコピーから各スライス内のチャンネルへの各メッセージを読み取りゴルーチンを起動したいチャンネルのスライスを作りますあなたが[ここ](https://blog.golang.org/pipelines#TOC_4)を開始することができます。 – kostix

+0

いいえ、fan-outはaskerが持っているものの、必要ではないものです。複数のクライアントが同じチャネルから読み取っています。 – Adrian

答えて

3

Mutiplexingは非常に簡単です:

// 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 
       } 
      } 
     }() 
    }) 
} 
+0

ありがとう、私はこれを使用していくつかの再利用可能なソリューションを考え出した:https://github.com/Lobaro/go-util/blob/master/broadcast/broadcast.go – Tarion

関連する問題