func wsWriter(ws *websocket.Conn) { graphIn := broker.Get().Subscribe() pingTicker := time.NewTicker(pingPeriod) defer func() { pingTicker.Stop() broker.Get().Unsubscribe(graphIn) ws.Close() }() // write the current graph state first, before entering loop graphToSock(ws, latestGraph) var g system.CoreGraph for { select { case <-pingTicker.C: // ensure client connection is healthy ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { return } case g = <-graphIn: graphToSock(ws, g) } } }
func graphToSock(ws *websocket.Conn, g system.CoreGraph) { j, err := graphToJSON(g) if err != nil { logrus.WithFields(logrus.Fields{ "system": "webapp", "err": err, }).Error("Error while marshaling graph into JSON for transmission over websocket") } if j != nil { ws.SetWriteDeadline(time.Now().Add(writeWait)) if err := ws.WriteMessage(websocket.TextMessage, j); err != nil { logrus.WithFields(logrus.Fields{ "system": "webapp", "err": err, }).Error("Error while writing graph data to websocket") return } } }
func writer(ws *websocket.Conn, lastMod time.Time) { lastError := "" pingTicker := time.NewTicker(pingPeriod) fileTicker := time.NewTicker(filePeriod) defer func() { pingTicker.Stop() fileTicker.Stop() ws.Close() }() for { select { case <-fileTicker.C: var p []byte var err error p, lastMod, err = readFileIfModified(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 } } } }