func writer(ws *websocket.Conn) { pingTicker := time.NewTicker(pingPeriod) nodesTicker := time.NewTicker(nodesPeriod) defer func() { pingTicker.Stop() nodesTicker.Stop() ws.Close() }() for { select { case <-nodesTicker.C: p := []byte(fmt.Sprintf("%v", nodesH)) if p != nil { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, p); err != nil { return } } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func (ws *WebSocker) writer(conn *websocket.Conn, user string, tmpl *template.Template) { pingTicker := time.NewTicker(pingPeriod) chl, chq := notifier.listen(user) ws.log.Println(user, "connected") defer func() { pingTicker.Stop() conn.Close() close(chq) ws.log.Println(user, "disconnected") }() for { var buf bytes.Buffer select { case p := <-chl: conn.SetWriteDeadline(time.Now().Add(writeWait)) buf.Reset() if err := tmpl.Execute(&buf, p); err != nil { ws.log.Println(err) return } if err := conn.WriteMessage(websocket.TextMessage, buf.Bytes()); err != nil { return } ws.log.Println("notified:", user) case <-pingTicker.C: conn.SetWriteDeadline(time.Now().Add(writeWait)) if err := conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil { ws.log.Println("ping:", err) return } } } }
// writer runs in a goroutine for each connected WS client. It emits all message returned by the observer. func writer(ws *websocket.Conn, a *ApiHandlers) { pingTicker := time.NewTicker(pingPeriod) s := a.getDBSubscriber() jww.INFO.Println("Opened WebSocket connection.") defer func(is *subscriber) { jww.INFO.Println("Closing WebSocket connection.") is.quitChan <- true pingTicker.Stop() ws.Close() }(s) for { select { case msg := <-s.bufChan: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteJSON(msg); err != nil { return } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func write(ws *websocket.Conn, mt int, payload []byte) error { if ws == nil { return errors.New("no web socket connection: ws") } ws.SetWriteDeadline(time.Now().Add(writeWait)) return ws.WriteMessage(mt, payload) }
// Pick requests off the RemoteServer queue and send them into the tunnel func wsWriter(rs *remoteServer, ws *websocket.Conn, ch chan int) { var req *remoteRequest var err error for { // fetch a request select { case req = <-rs.requestQueue: // awesome... case _ = <-ch: // time to close shop rs.log.Info("WS closing on signal", "ws", wsp(ws)) ws.Close() return } //log.Printf("WS->%s#%d start %s", req.token, req.id, req.info) // See whether the request has already expired if req.deadline.Before(time.Now()) { req.replyChan <- responseBuffer{ err: errors.New("Timeout before forwarding the request"), } req.log.Info("WS SND timeout before sending", "ago", time.Now().Sub(req.deadline).Seconds()) continue } // write the request into the tunnel ws.SetWriteDeadline(time.Now().Add(time.Minute)) var w io.WriteCloser w, err = ws.NextWriter(websocket.BinaryMessage) // got an error, reply with a "hey, retry" to the request handler if err != nil { break } // write the request Id _, err = fmt.Fprintf(w, "%04x", req.id) if err != nil { break } // write the request itself _, err = req.buffer.WriteTo(w) if err != nil { break } // done err = w.Close() if err != nil { break } req.log.Info("WS SND", "info", req.info) } // tell the sender to retry the request req.replyChan <- responseBuffer{err: RetryError} req.log.Info("WS error causes retry") // close up shop ws.WriteControl(websocket.CloseMessage, nil, time.Now().Add(5*time.Second)) time.Sleep(2 * time.Second) ws.Close() }
func NewCcusConn(ws *websocket.Conn, cc_in chan updateInfo) *ccusConn { log.Printf("ws[%s]:new connect %s", ws.RemoteAddr(), ws.LocalAddr()) ws.SetReadDeadline(time.Now().Add(pongWait)) ws.SetWriteDeadline(time.Now().Add(writeWait)) pc := &ccusConn{} pc.ws = ws pc.cc_in = cc_in go pc.receiver() return pc }
// wsConnHandler starts goroutines for forever reading from, and writing to, a // websocket connection. Reads can be read from the ch_r channel, writes be // sent to the ch_w channel. // // When a read from the websocket returns an error (which for example happens // when the connection is closed), the read goroutine will terminate, but not // right away. The faulty read is available on the read channel for a while // before a timeout kicks in and the channel is closed. This is a little weird, // but it ensures that faulty reads can be read by some listening goroutine, // while it is at the same time guaranteed that the goroutine terminates even // if there is no listener. // // When the caller closes the write channel (don't forget to do that!), // wsConnHandler will close the websocket connection (with Close(), not with a // control message) and terminate both goroutines. If you want to close the // websocket with a control message, just do it by sending a control message // directly over the conn object (this is legal). After that, close the write // channel. func wsConnHandler(c *websocket.Conn) (<-chan *wsReadResult, chan<- *wsWriteCmd) { // channels we expose ch_r := make(chan *wsReadResult) ch_w := make(chan *wsWriteCmd) // reader go func() { for cont := true; cont; { // read from websocket forever res := new(wsReadResult) c.SetReadDeadline(time.Now().Add( time.Duration(appVars.config.WebsocketConnectionTimeoutS) * time.Second)) res.messageType, res.data, res.err = c.ReadMessage() // err on socket close if res.err == nil { // got a message? send to read channel and read from websocket again ch_r <- res } else { log.Printf("ws conn handler reader got error (normal at close)") // got an error from the read? offer on read channel until timeout. // Eventually, break out of loop select { case ch_r <- res: cont = false case <-time.After(30 * time.Second): cont = false } } } close(ch_r) log.Printf("ws conn handler reader terminates") return }() // writer go func() { // recv from ch_w and send what is received over WriteMessage until channel // is closed for cmd := range ch_w { c.SetWriteDeadline(time.Now().Add( time.Duration(appVars.config.WebsocketConnectionTimeoutS) * time.Second)) err := c.WriteMessage(cmd.messageType, cmd.data) cmd.ch_ret <- err } // when channel is closed, close the websocket log.Printf("ws conn handler writer closes websocket connection and terminates") c.Close() // reader goroutine will get an error from ReadMessage() return }() return ch_r, ch_w }
func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) { defer ws.Close() s := bufio.NewScanner(r) for s.Scan() { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil { break } } if s.Err() != nil { log.Println("scan:", s.Err()) } close(done) log.Println("exit stdout pump") }
func (ws *Websocket) Writer(c *goWs.Conn, closed <-chan bool) { ws.watcher.Start() defer ws.watcher.Stop() defer c.Close() for { select { case data := <-ws.watcher.C.Raw: c.SetWriteDeadline(time.Now().Add(WriteTimeout)) err := c.WriteMessage(goWs.TextMessage, MdConverter.Convert(*data)) if err != nil { return } case <-closed: return } } }
// pumpStdout handles reading data from stdout of the process and writing // it to websocket connection. func pumpStdout(conn *websocket.Conn, stdout io.Reader, done chan struct{}) { go pinger(conn, done) defer func() { conn.Close() close(done) // make sure to close the pinger when we are done. }() s := bufio.NewScanner(stdout) for s.Scan() { conn.SetWriteDeadline(time.Now().Add(writeWait)) if err := conn.WriteMessage(websocket.TextMessage, bytes.TrimSpace(s.Bytes())); err != nil { break } } if s.Err() != nil { conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, s.Err().Error()), time.Time{}) } }
func writer(ws *websocket.Conn, lastMod time.Time, which string) { pingTicker := time.NewTicker(pingPeriod) updateTicker := time.NewTicker(updatePeriod) defer func() { pingTicker.Stop() updateTicker.Stop() ws.Close() }() for { select { case <-updateTicker.C: var r []Result var t []interface{} var err error if which == "score" { r, lastMod, err = getTeamScoreIfModified(lastMod) } else if which == "service" { t, lastMod, err = getServiceIfModified(lastMod) } if err != nil { Logger.Printf("Could not get websocket team score: %v\n", err) } if r != nil || t != nil { ws.SetWriteDeadline(time.Now().Add(writeWait)) if which == "service" { if err := ws.WriteJSON(t); err != nil { return } } else { if err := ws.WriteJSON(r); err != nil { return } } } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func writer(ws *websocket.Conn, lastMod time.Time, filename string) { lastError := "" pingTicker := time.NewTicker(pingPeriod) fileTicker := time.NewTicker(filePeriod) defer func() { pingTicker.Stop() fileTicker.Stop() ws.Close() }() var offset int64 for { select { case <-fileTicker.C: var p []byte var err error p, lastMod, offset, err = readFileIfModified(filename, offset, lastMod) if err != nil { if s := err.Error(); s != lastError { lastError = s p = []byte(lastError) } } else { lastError = "" } if p != nil { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, p); err != nil { return } } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func pumpStdout(ws *websocket.Conn, r io.Reader, done chan struct{}) { defer func() { }() s := bufio.NewScanner(r) for s.Scan() { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, s.Bytes()); err != nil { ws.Close() break } } if s.Err() != nil { log.Println("scan:", s.Err()) } close(done) ws.SetWriteDeadline(time.Now().Add(writeWait)) ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) time.Sleep(closeGracePeriod) ws.Close() }
func writer(ws *websocket.Conn, uiMsgChan chan types.UIUpdateMsg) { pingTicker := time.NewTicker(pingPeriod) defer func() { pingTicker.Stop() ws.Close() }() for { select { case msg := <-uiMsgChan: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteJSON(msg); err != nil { return } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func (this *subServer) wsWritePump(clientGone chan struct{}, ws *websocket.Conn, fetcher store.Fetcher) { defer fetcher.Close() var err error for { select { case msg := <-fetcher.Messages(): ws.SetWriteDeadline(time.Now().Add(time.Second * 10)) // FIXME because of buffer, client recv 10, but kateway written 100, then // client quit... if err = ws.WriteMessage(websocket.BinaryMessage, msg.Value); err != nil { log.Error("%s: %v", ws.RemoteAddr(), err) return } if err = fetcher.CommitUpto(msg); err != nil { log.Error(err) // TODO add more ctx } case err = <-fetcher.Errors(): // TODO log.Error(err) case <-this.timer.After(this.wsPongWait / 3): ws.SetWriteDeadline(time.Now().Add(time.Second * 10)) if err = ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { log.Error("%s: %v", ws.RemoteAddr(), err) return } case <-this.gw.shutdownCh: return case <-clientGone: return } } }
func wsWriter(ws *websocket.Conn, mc chan string) { pingTicker := time.NewTicker(pingPeriod) defer func() { pingTicker.Stop() ws.Close() }() for { select { case msg := <-mc: log.Println("Writing: " + msg) if err := ws.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil { return } case <-pingTicker.C: log.Println("Sending ping") ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func writer(ws *websocket.Conn, fn string) { pingTicker := time.NewTicker(pingPeriod) fileTicker := time.NewTicker(filePeriod) defer func() { pingTicker.Stop() fileTicker.Stop() ws.Close() }() var r *bufio.Reader if !stdIn { f, _ := os.Open(fn) r = bufio.NewReader(f) defer f.Close() } else { r = bufio.NewReader(os.Stdin) } for { select { case <-fileTicker.C: p, err := r.ReadBytes('\n') if err != io.EOF { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, p); err != nil { return } } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
// Reads incoming data from the websocket and forwards it to stdout. func readWS(ws *websocket.Conn, query *regexp.Regexp, done chan struct{}) { defer func() { done <- struct{}{} }() ws.SetPingHandler(func(string) error { ws.SetWriteDeadline(time.Now().Add(writeTimeout)) return ws.WriteMessage(websocket.PongMessage, []byte{}) }) for { _, msg, err := ws.ReadMessage() if err != nil { return } var log LogMessage err = json.Unmarshal(msg, &log) if err == nil { if query == nil || query.MatchString(log.Message) { logrus.Printf("%s - %s", log.Timestamp, log.Message) } } else { logrus.StandardLogger().Out.Write(msg) } } }
func write(ws *websocket.Conn, opCode int, payload []byte) error { ws.SetWriteDeadline(time.Now().Add(WRITE_WAIT)) return ws.WriteMessage(opCode, payload) }
// Writes a message with the given message type (mt) and payload. func ws_write(ws *websocket.Conn, mt int, payload []byte) error { ws.SetWriteDeadline(time.Now().Add(writeWait)) return ws.WriteMessage(mt, payload) }
// timeout error on all network activity func setDeadline(ws *websocket.Conn, d time.Duration) { ws.SetReadDeadline(time.Now().Add(d)) ws.SetWriteDeadline(time.Now().Add(d)) }
// Stream will init a new pubsub.KafkaPublisher and pubsub.KafkaSubscriber // then upgrade the current request to a websocket connection. Any messages // consumed from Kafka will be published to the web socket and vice versa. func (s *StreamService) Stream(w http.ResponseWriter, r *http.Request) { cfg := *s.cfg cfg.Topic = topicName(web.GetInt64Var(r, "stream_id")) server.LogWithFields(r).WithField("topic", cfg.Topic).Info("new stream req") sub, err := pubsub.NewKafkaSubscriber(&cfg, zeroOffset, discardOffset) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to create sub") http.Error(w, "unable to create subscriber: "+err.Error(), http.StatusBadRequest) return } defer func() { if err := sub.Stop(); err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to stop sub") } }() var pub *pubsub.KafkaPublisher pub, err = pubsub.NewKafkaPublisher(&cfg) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to create pub") http.Error(w, "unable to create publisher: "+err.Error(), http.StatusBadRequest) return } defer func() { if err := pub.Stop(); err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to stop pub") } }() var ws *websocket.Conn ws, err = upgrader.Upgrade(w, r, nil) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to create websocket") http.Error(w, "unable to create websocket: "+err.Error(), http.StatusBadRequest) return } defer func() { if err := ws.Close(); err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to close ws") } }() // start consumer, emit to ws noopTicker := time.NewTicker(time.Second * 5) subscriberDone := make(chan bool, 1) stopSubscriber := make(chan bool, 1) go func() { defer func() { subscriberDone <- true }() var ( payload []byte msgs = sub.Start() ) for { select { case msg := <-msgs: payload = msg.Message() err = ws.SetWriteDeadline(time.Now().Add(time.Second * 30)) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to write deadline") } err = ws.WriteMessage(websocket.TextMessage, payload) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to write ws message") } err = msg.Done() if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to mark gizmo message as done") } case <-noopTicker.C: err = ws.SetWriteDeadline(time.Now().Add(time.Second * 30)) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to write deadline") } if err := ws.WriteMessage(websocket.PingMessage, []byte("ping")); err != nil { server.LogWithFields(r).WithField("error", err).Error("error writing ws message") return } case <-stopSubscriber: return } } }() // start producer, emit to kafka producerDone := make(chan bool, 1) go func() { defer func() { producerDone <- true stopSubscriber <- true server.LogWithFields(r).WithField("topic", cfg.Topic).Info("closing stream req") }() var ( messageType int payload []byte err error read io.Reader ) for { messageType, read, err = ws.NextReader() if err != nil { if err != io.EOF { server.LogWithFields(r).WithField("error", err).Error("error reading message") } return } switch messageType { case websocket.TextMessage: payload, err = ioutil.ReadAll(read) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to read payload") return } err = pub.PublishRaw(cfg.Topic, payload) if err != nil { server.LogWithFields(r).WithField("error", err).Error("unable to publish payload") return } case websocket.PingMessage, websocket.PongMessage, websocket.BinaryMessage: server.LogWithFields(r).Info("discarding message type: ", messageType) case websocket.CloseMessage: server.LogWithFields(r).Info("closing websocket") return } } }() <-subscriberDone <-producerDone noopTicker.Stop() server.LogWithFields(r).WithField("topic", cfg.Topic).Info("leaving stream req") }
func writer(ws *websocket.Conn) { pingTicker := time.NewTicker(pingPeriod) fileTicker := time.NewTicker(dataPushPeriod) defer func() { pingTicker.Stop() fileTicker.Stop() ws.Close() }() timeout := time.Duration(1 * time.Second) httpClient := http.Client{ Timeout: timeout, } for { select { case <-fileTicker.C: var clusterState ClusterState app, err := client.Application("cattlestore") if err != nil { log.Printf("Not scaling: %s", err) } clusterState.NrOfInstances = app.Instances ops_t, max_t := 0.0, 0.0 if app != nil && err == nil { for _, task := range app.Tasks { resp, err := httpClient.Get(fmt.Sprintf("http://172.17.0.1:%d/info", task.Ports[0])) if err != nil { continue } state, err := ioutil.ReadAll(resp.Body) if err != nil { continue } f := State{} json.Unmarshal(state, &f) clusterState.Instances = append(clusterState.Instances, Instance{ Id: task.ID[12:20], Ops: f.Ops, Max: f.Max, }) ops_t += float64(f.Ops) max_t += float64(f.Max) } } go scaleUp(ops_t, max_t) p, err := json.Marshal(clusterState) if err != nil { continue } // p := []byte(`[{"id":"6cd8a58f","max":24,"ops":24},{"id":"6cd8a58e","max":24,"ops":18}, // {"id":"1cd8a58f","max":24,"ops":24},{"id":"4cd8a58e","max":24,"ops":18}, // {"id":"2cd8a58f","max":24,"ops":24},{"id":"5cd8a58e","max":24,"ops":18}, // {"id":"3cd8a58f","max":24,"ops":24},{"id":"7cd8a58e","max":24,"ops":18}, {"id":"6cdf3444","max":30,"ops":12},{"id":"6cbdca8b","max":13,"ops":3},{"id":"6ce8f854","max":13,"ops":12}]`) if p != nil { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, p); err != nil { return } } case <-pingTicker.C: ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } } } }
func ping(ws *websocket.Conn) error { ws.SetWriteDeadline(time.Now().Add(writeWait)) return ws.WriteMessage(websocket.PingMessage, []byte{}) }