2017-12-01 23 views
0

이동 중에도 일부 채널 출력을 멀티플렉싱하는 솔루션을 찾고 있습니다.이동 중에 채널 출력을 다중화하는 방법

나는 하나의 채널에 보내는 io.Reader에서 읽은 데이터 원본을 가지고 있습니다. 반대편에는 채널에서 읽는 websocket 요청 처리기가 있습니다. 이제 두 클라이언트가 websocket 연결을 생성합니다. 둘 다 동일한 채널에서 읽지 만 각각은 메시지의 일부만 얻습니다.

코드 예 (간체) ReadLog() 회 호출되면

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 
} 

이제 두 번째 전화는 문제가 상술 리드 제 호출에서 생성 된 채널을 반환한다.

질문 : 적절한 멀티플렉싱 방법?

송신 사이트 또는 수신 사이트의 멀티플렉싱에 신경 쓰는 것이 더 쉽고/더 쉽습니다.

리시버에서 채널을 숨기고 콜백으로 작업해야합니까?

저는 지금 조금 붙어 있습니다. 어떤 힌트라도 환영합니다.

+1

당신 '당신이 멀티 플렉스 원래 채널 복사에서 각 슬라이스의 채널에 각 메시지를 읽는 goroutine을 시작하려는 채널의 조각을 다시 팬 아웃 (fan-out)이라고하면, [여기] (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