code: func (conn *WebsocketConnection) waitForReader() error {
  	// no existing readers, wait for one
  	for {
  		opCode, reader, err := conn.ws.NextReader()
  		if err != nil {
  			return err
  		}
  
  		switch opCode {
  		case websocket.BinaryMessage:
  			// binary packet
  			conn.reader = reader
  			return nil
  
  		case websocket.TextMessage:
  			// plain text package
  			b, err := ioutil.ReadAll(reader)
  			if err == nil {
  				conn.textChan <- b
  			}
  
  		case websocket.PingMessage:
  			// receeived a ping, so send a pong
  			go func() {
  				conn.writeMutex.Lock()
  				defer conn.writeMutex.Unlock()
  				conn.ws.WriteControl(websocket.PongMessage, []byte{}, time.Now().Add(conn.writeTimeout))
  			}()
  
  		case websocket.PongMessage:
  			// received a pong, update read deadline
  			conn.ws.SetReadDeadline(time.Now().Add(conn.readTimeout))
  
  		case websocket.CloseMessage:
  			// received close, so return EOF
  			return io.EOF
  		}
  	}
  }
docs: // This method loops until a binary opcode comes in and returns its reader.
  // While looping it will receive and process other opcodes, such as pings.