// @Title getSignals // @router /signal/:name [get] func (c *ClientController) GetSignals() { name := c.GetString(":name") defer c.ServeJSON() beego.Debug("[C] Got name:", name) if name != "" { host := &models.Hosts{ Name: name, } hosts, err := models.GetHosts(host, 0, 0) if err != nil { c.Data["json"] = map[string]string{ "message": fmt.Sprint("Failed to get with name:", name), "error": err.Error(), } beego.Warn("[C] Got error:", err) c.Ctx.Output.SetStatus(http.StatusInternalServerError) return } if len(hosts) == 0 { beego.Debug("[C] Got nothing with name:", name) c.Ctx.Output.SetStatus(http.StatusNotFound) return } c.Data["json"] = models.GetSignals(hosts[0].Id) c.Ctx.Output.SetStatus(http.StatusOK) } }
// @Title createSignal // @router /signal/:name [post] func (c *ClientController) PostSignal() { name := c.GetString(":name") defer c.ServeJSON() beego.Debug("[C] Got name:", name) if name != "" { host := &models.Hosts{ Name: name, } hosts, err := models.GetHosts(host, 0, 0) if err != nil { c.Data["json"] = map[string]string{ "message": fmt.Sprint("Failed to get with name:", name), "error": err.Error(), } beego.Warn("[C] Got error:", err) c.Ctx.Output.SetStatus(http.StatusInternalServerError) return } if len(hosts) == 0 { beego.Debug("[C] Got nothing with name:", name) c.Ctx.Output.SetStatus(http.StatusNotFound) return } var signal models.Signal err = json.Unmarshal(c.Ctx.Input.RequestBody, &signal) if err != nil { beego.Warn("[C] Got error:", err) c.Data["json"] = map[string]string{ "message": "Bad request", "error": err.Error(), } c.Ctx.Output.SetStatus(http.StatusBadRequest) return } beego.Debug("[C] Got data:", signal) id, err := models.AddSignal(hosts[0].Id, signal) if err != nil { beego.Warn("[C] Got error:", err) c.Data["json"] = map[string]string{ "message": "Failed to add new signal", "error": err.Error(), } c.Ctx.Output.SetStatus(http.StatusBadRequest) return } c.Data["json"] = map[string]string{ "id": id, } c.Ctx.Output.SetStatus(http.StatusCreated) } }
// @Title getSignalsWs // @router /signal/:name/ws [get] func (c *ClientController) WebSocket() { name := c.GetString(":name") beego.Debug("[C] Got name:", name) if name != "" { host := &models.Hosts{ Name: name, } hosts, err := models.GetHosts(host, 1, 0) if err != nil { c.Data["json"] = map[string]string{ "message": fmt.Sprint("Failed to get with name:", name), "error": err.Error(), } beego.Warn("[C] Got error:", err) c.Ctx.Output.SetStatus(http.StatusInternalServerError) c.ServeJSON() return } if len(hosts) == 0 { beego.Debug("[C] Got nothing with name:", name) c.Ctx.Output.SetStatus(http.StatusNotFound) c.ServeJSON() return } HostId := hosts[0].Id ws, err := websocket.Upgrade( c.Ctx.ResponseWriter, c.Ctx.Request, nil, 1024, 1024) if err != nil { c.Data["json"] = map[string]string{ "message": "Failed on upgrading to websocket", "error": err.Error(), } beego.Warn("[C] Got error:", err) c.Ctx.Output.SetStatus(http.StatusInternalServerError) c.ServeJSON() return } defer ws.Close() tick, err := beego.AppConfig.Int64("websocket::pingperiod") if err != nil { tick = 5 } ticker := time.NewTicker( time.Duration(tick) * time.Second) defer ticker.Stop() timeout, err := beego.AppConfig.Int64("websocket::timeout") if err != nil { timeout = 10 } ws.SetReadDeadline(time.Now().Add( time.Duration(timeout) * time.Second), ) ws.SetWriteDeadline(time.Now().Add( time.Duration(timeout) * time.Second), ) ws.SetPongHandler(func(string) error { beego.Debug("Host:", name, "is still alive.") ws.SetReadDeadline(time.Now().Add( time.Duration(timeout) * time.Second), ) ws.SetWriteDeadline(time.Now().Add( time.Duration(timeout) * time.Second), ) return nil }) var c chan models.Signal c, ok := models.SignalChannels[HostId] if !ok { c = make(chan models.Signal, 1024) models.SignalChannels[HostId] = c } // Start read routine go func() { defer ws.Close() for { _, bConfirm, err := ws.ReadMessage() if websocket.IsCloseError(err, websocket.CloseGoingAway) { beego.Info("Host", name, "is offline.") return } else if err != nil { beego.Warn("Error on reading:", err.Error()) return } s := strings.Split(string(bConfirm), " ") if s[0] == ClientWebSocketReplyDone { models.DeleteSignal(HostId, s[1]) } } }() for { select { case s := <-models.SignalChannels[HostId]: ws.WriteJSON(s) case <-ticker.C: beego.Debug("Websocket ping:", name) err := ws.WriteMessage(websocket.PingMessage, []byte{}) if err != nil { beego.Warn("Got error on ping", err.Error()) return } } } } }