// readPump reads from the websocket and sends to inbound channel. // Expects to receive PONGs at specified interval, or logs an error and returns. func (r *Remote) readPump(inbound chan<- []byte) { r.ws.SetReadDeadline(time.Now().Add(pongWait)) r.ws.SetPongHandler(func(string) error { r.ws.SetReadDeadline(time.Now().Add(pongWait)); return nil }) for { _, message, err := r.ws.ReadMessage() if err != nil { glog.Errorln(err) return } glog.V(2).Infoln(dump(message)) r.ws.SetReadDeadline(time.Now().Add(pongWait)) inbound <- message } }
// Consumes from the outbound channel and sends them over the websocket. // Also sends PING messages at the specified interval. // Returns when outbound channel is closed, or an error is encountered. func (r *Remote) writePump(outbound <-chan interface{}) { ticker := time.NewTicker(pingPeriod) defer ticker.Stop() for { select { // An outbound message is available to send case message, ok := <-outbound: if !ok { r.ws.WriteMessage(websocket.CloseMessage, []byte{}) return } b, err := json.Marshal(message) if err != nil { // Outbound message cannot be JSON serialized (log it and continue) glog.Errorln(err) continue } glog.V(2).Infoln(dump(b)) if err := r.ws.WriteMessage(websocket.TextMessage, b); err != nil { glog.Errorln(err) return } // Time to send a ping case <-ticker.C: if err := r.ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { glog.Errorln(err) return } } } }