1 Star 0 Fork 41

cl5/rttys

forked from 赵建辉/rttys 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
command.go 2.67 KB
一键复制 编辑 原始数据 按行查看 历史
赵建辉 提交于 2021-01-22 21:40 +08:00 . refactor
package main
import (
"context"
"io/ioutil"
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/gin-gonic/gin"
"github.com/zhaojh329/rttys/client"
"github.com/zhaojh329/rttys/utils"
jsoniter "github.com/json-iterator/go"
)
const commandTimeout = 30 // second
const (
rttyCmdErrInvalid = 1001
rttyCmdErrOffline = 1002
rttyCmdErrTimeout = 1003
)
var cmdErrMsg = map[int]string{
rttyCmdErrInvalid: "invalid format",
rttyCmdErrOffline: "device offline",
rttyCmdErrTimeout: "timeout",
}
type commandInfo struct {
Cmd string `json:"cmd"`
Username string `json:"username"`
Password string `json:"password"`
}
type commandReq struct {
cancel context.CancelFunc
dev client.Client
c *gin.Context
data []byte
}
var commands sync.Map
func handleCmdResp(br *broker, data []byte) {
token := jsoniter.Get(data, "token").ToString()
if req, ok := commands.Load(token); ok {
req := req.(*commandReq)
req.c.String(http.StatusOK, jsoniter.Get(data, "attrs").ToString())
req.cancel()
}
}
func cmdErrReply(err int, req *commandReq) {
req.c.JSON(http.StatusOK, gin.H{
"err": err,
"msg": cmdErrMsg[err],
})
req.cancel()
}
func handleCmdReq(br *broker, c *gin.Context) {
devid := c.Param("devid")
ctx, cancel := context.WithCancel(context.Background())
req := &commandReq{
cancel: cancel,
c: c,
}
dev, ok := br.devices[devid]
if !ok {
cmdErrReply(rttyCmdErrOffline, req)
return
}
req.dev = dev
content, err := ioutil.ReadAll(c.Request.Body)
if err != nil {
c.Status(http.StatusBadRequest)
return
}
cmdInfo := commandInfo{}
err = jsoniter.Unmarshal(content, &cmdInfo)
if err != nil || cmdInfo.Cmd == "" {
cmdErrReply(rttyCmdErrInvalid, req)
return
}
token := utils.GenUniqueID("cmd")
params := jsoniter.Get(content, "params")
data := make([]string, 5)
data[0] = jsoniter.Get(content, "username").ToString()
data[1] = jsoniter.Get(content, "password").ToString()
data[2] = jsoniter.Get(content, "cmd").ToString()
data[3] = token
data[4] = string(byte(params.Size()))
req.data = []byte(strings.Join(data, string(byte(0))))
for i := 0; i < params.Size(); i++ {
req.data = append(req.data, params.Get(i).ToString()...)
req.data = append(req.data, 0)
}
br.cmdReq <- req
waitTime := commandTimeout
wait := c.Query("wait")
if wait != "" {
waitTime, _ = strconv.Atoi(wait)
}
if waitTime == 0 {
c.Status(http.StatusOK)
return
}
commands.Store(token, req)
if waitTime < 0 || waitTime > commandTimeout {
waitTime = commandTimeout
}
tmr := time.NewTimer(time.Second * time.Duration(waitTime))
select {
case <-tmr.C:
cmdErrReply(rttyCmdErrTimeout, req)
commands.Delete(token)
case <-ctx.Done():
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/dadba/rttys.git
git@gitee.com:dadba/rttys.git
dadba
rttys
rttys
master

搜索帮助