ожидая одновременного подключения к сокету и канала - PullRequest
1 голос
/ 30 марта 2020

У меня есть подпрограмма go, которая должна ожидать соединения с сокетом (входящее сообщение от клиента), а также есть канал, с которого он читает, оба в одно и то же время. Не знаете, как это сделать в рутине go, если это вообще возможно? Любой пример кода будет оценен.

Я видел, как это сделать на каналах https://gobyexample.com/non-blocking-channel-operations, но у меня есть комбинация веб-сокета и канала.

Из этого поста https://github.com/gorilla/websocket/issues/122 это кажется невозможным (я использую гориллу), но оно старое и интересно, было ли что-то новое.

1 Ответ

1 голос
/ 30 марта 2020

Чтобы ожидать два потока событий одновременно в Go, вы должны использовать оператор select, но он работает только на каналах.

Таким образом, каноническое решение состоит в том, что имеется процедура, которая читает из сокета (блокирует) и помещает данные в канал. Затем вы можете select на этом канале вместе с другим каналом.

Псевдокод:

// Want to wait on channel 'chan' and socket connection 'conn'

// sockCh is used to notify of new data arrived on the socket
sockCh := make(chan []byte)

// This goroutine listens on the socket and pushes all data it gets
// into sockCh.
go func() {
  for {
    buf := make([]byte, 2048)
    n, err := conn.Read(buf)
    if err != nil && err != io.EOF {
      log.Println("read error", err)
      return
    }
    if n == 0 {
      return
    }
    sockCh <- buf
  }
}()

select {
case buf := <-sockCh:
  // got buf from socket
case stuff := <-chan:
  // got stuff from channel
}
...