@ -1,45 +1,47 @@ | |||||
package main | package main | ||||
import ( | import ( | ||||
"github.com/gofiber/fiber/v2" | |||||
"time" | |||||
"github.com/gofiber/fiber/v2" | |||||
"log" | |||||
"time" | |||||
) | ) | ||||
type StatusResult struct { | type StatusResult struct { | ||||
Code string `json:"code"` | |||||
Message string `json:"msg"` | |||||
Timestamp int64 `json:"timestamp"` | |||||
Code string `json:"code"` | |||||
Message string `json:"msg"` | |||||
Timestamp int64 `json:"timestamp"` | |||||
} | } | ||||
type StatusResultEx struct { | type StatusResultEx struct { | ||||
StatusResult | |||||
Scene string `json:"scene"` | |||||
SequenceId int `json:"sequenceId"` | |||||
StatusResult | |||||
Scene string `json:"scene"` | |||||
SequenceId int64 `json:"sequenceId"` | |||||
} | } | ||||
func failureResponse(ctx *fiber.Ctx, code string, msg string, stat int) error { | func failureResponse(ctx *fiber.Ctx, code string, msg string, stat int) error { | ||||
ctx.Response().SetStatusCode(stat) | |||||
var ret = make(map[string]interface{}) | |||||
ret["status"] = StatusResult{Code: code, Message: msg, Timestamp: time.Now().Unix()} | |||||
return ctx.JSON(ret) | |||||
log.Println("failureResponse:> ", ctx.Request().URI(), msg) | |||||
ctx.Response().SetStatusCode(stat) | |||||
var ret = make(map[string]interface{}) | |||||
ret["status"] = StatusResult{Code: code, Message: msg, Timestamp: time.Now().Unix()} | |||||
return ctx.JSON(ret) | |||||
} | } | ||||
func successResponse(ctx *fiber.Ctx, msg string) error { | func successResponse(ctx *fiber.Ctx, msg string) error { | ||||
var ret = make(map[string]interface{}) | |||||
ret["status"] = StatusResult{Code: "0", Message: msg, Timestamp: time.Now().Unix()} | |||||
return ctx.JSON(ret) | |||||
var ret = make(map[string]interface{}) | |||||
ret["status"] = StatusResult{Code: "0", Message: msg, Timestamp: time.Now().Unix()} | |||||
return ctx.JSON(ret) | |||||
} | } | ||||
func successResponseEx(ctx *fiber.Ctx, msg string, scene string, seq int) error { | |||||
var ret = make(map[string]interface{}) | |||||
ret["status"] = StatusResultEx{ | |||||
StatusResult: StatusResult{ | |||||
Code: "0", | |||||
Message: msg, | |||||
Timestamp: time.Now().Unix(), | |||||
}, | |||||
SequenceId: seq, | |||||
Scene: scene, | |||||
} | |||||
return ctx.JSON(ret) | |||||
func successResponseEx(ctx *fiber.Ctx, msg string, scene string, seq int64) error { | |||||
var ret = make(map[string]interface{}) | |||||
ret["status"] = StatusResultEx{ | |||||
StatusResult: StatusResult{ | |||||
Code: "0", | |||||
Message: msg, | |||||
Timestamp: time.Now().Unix(), | |||||
}, | |||||
SequenceId: seq, | |||||
Scene: scene, | |||||
} | |||||
return ctx.JSON(ret) | |||||
} | } |
@ -1,28 +1,133 @@ | |||||
package main | package main | ||||
import ( | import ( | ||||
"github.com/gofiber/fiber/v2" | |||||
"errors" | |||||
"github.com/gofiber/fiber/v2" | |||||
"log" | |||||
"time" | |||||
) | ) | ||||
type TestCommand struct { | type TestCommand struct { | ||||
Command string `json:"cmd"` | |||||
SequenceId int `json:"sequenceId"` | |||||
Command string `json:"cmd"` | |||||
SequenceId int64 `json:"sequenceId"` | |||||
} | } | ||||
var currentTest *TestCommand | var currentTest *TestCommand | ||||
var testChannel chan *TestCommand | |||||
var testStopChannel chan bool | |||||
func setTestCmd(c *fiber.Ctx) error { | func setTestCmd(c *fiber.Ctx) error { | ||||
var testCmd TestCommand | |||||
if err := c.BodyParser(&testCmd); nil != err { | |||||
return failureResponse(c, "-1", err.Error(), 400) | |||||
} else if nil == currentScene { | |||||
return failureResponse(c, "1", "not in a working scene", 400) | |||||
} else { | |||||
currentTest = &testCmd | |||||
return successResponse(c, "Updated successfully.") | |||||
} | |||||
var testCmd TestCommand | |||||
if err := c.BodyParser(&testCmd); nil != err { | |||||
return failureResponse(c, "-1", err.Error(), 400) | |||||
} else if nil == currentScene { | |||||
return failureResponse(c, "1", "not in a working scene", 400) | |||||
} else { | |||||
currentTest = &testCmd | |||||
switch testCmd.Command { | |||||
case "START": | |||||
log.Println("START ...") | |||||
if nil != currentTest { | |||||
return failureResponse(c, "2", "A test already started", 403) | |||||
} | |||||
if e := recogTaskProc(&testCmd); nil != e { | |||||
return failureResponse(c, "3", e.Error(), 409) | |||||
} | |||||
case "STOP": | |||||
log.Println("STOP ...") | |||||
case "CANCEL": | |||||
log.Println("CANCEL ...") | |||||
default: | |||||
log.Println("UNKNOWN ...") | |||||
} | |||||
return successResponse(c, "Updated successfully.") | |||||
} | |||||
} | |||||
func pullUpTask(seq int64) error { | |||||
var tk = time.NewTicker(time.Second * 3) | |||||
defer func() { | |||||
tk.Stop() | |||||
}() | |||||
for { | |||||
select { | |||||
case <-testStopChannel: | |||||
return nil | |||||
case <-tk.C: | |||||
log.Println("===") | |||||
} | |||||
} | |||||
} | |||||
func standJumpTask(seq int64) error { | |||||
var tk = time.NewTicker(time.Second * 3) | |||||
defer func() { | |||||
tk.Stop() | |||||
}() | |||||
for { | |||||
select { | |||||
case <-testStopChannel: | |||||
return nil | |||||
case <-tk.C: | |||||
log.Println("===") | |||||
} | |||||
} | |||||
} | |||||
func sitUpsTask(seq int64) error { | |||||
var tk = time.NewTicker(time.Second * 3) | |||||
defer func() { | |||||
tk.Stop() | |||||
}() | |||||
for { | |||||
select { | |||||
case <-testStopChannel: | |||||
return nil | |||||
case <-tk.C: | |||||
log.Println("===") | |||||
} | |||||
} | |||||
} | |||||
func raceTask(seq int64) error { | |||||
var tk = time.NewTicker(time.Second * 3) | |||||
defer func() { | |||||
tk.Stop() | |||||
}() | |||||
for { | |||||
select { | |||||
case <-testStopChannel: | |||||
return nil | |||||
case <-tk.C: | |||||
log.Println("===") | |||||
} | |||||
} | |||||
} | |||||
func recogTaskProc(cmd *TestCommand) error { | |||||
testStopChannel = make(chan bool) | |||||
if nil == currentScene { | |||||
return errors.New("invalid scene state") | |||||
} | |||||
if nil == currentScene.proc { | |||||
return errors.New("invalid scene mode processor") | |||||
} | |||||
currentTest = cmd | |||||
go func() { | |||||
defer func() { | |||||
close(testStopChannel) | |||||
currentTest = nil | |||||
}() | |||||
if e := currentScene.proc(cmd.SequenceId); nil != e { | |||||
log.Println(">>>>", e) | |||||
} | |||||
}() | |||||
return nil | |||||
} | } | ||||
func init() { | func init() { | ||||
currentTest = nil | |||||
currentTest = nil | |||||
testChannel = nil | |||||
testStopChannel = nil | |||||
} | } |
@ -1,71 +1,119 @@ | |||||
package main | package main | ||||
import ( | import ( | ||||
"errors" | |||||
"github.com/gofiber/fiber/v2" | |||||
"net/url" | |||||
"errors" | |||||
"github.com/gofiber/fiber/v2" | |||||
"log" | |||||
"net/url" | |||||
"time" | |||||
) | ) | ||||
var currentScene *SceneCommand | |||||
type SceneCommand struct { | type SceneCommand struct { | ||||
Scene string `json:"scene"` | |||||
PushUrl string `json:"pushUrl"` | |||||
CameraUrls []string `json:"cameraURls"` | |||||
Scene string `json:"scene"` | |||||
PushUrl string `json:"pushUrl"` | |||||
CameraUrls []string `json:"cameraURls"` | |||||
proc func(int64) error | |||||
} | } | ||||
var currentScene *SceneCommand | |||||
var sceneStopChannel chan bool | |||||
func validateSceneCmd(cmd SceneCommand) error { | func validateSceneCmd(cmd SceneCommand) error { | ||||
switch cmd.Scene { | |||||
case "pullUp", "standJump", "sitUps": | |||||
if len(cmd.CameraUrls) < 1 { | |||||
return errors.New("cameraUrls can not less than 1") | |||||
} | |||||
case "race": | |||||
if len(cmd.CameraUrls) < 2 { | |||||
return errors.New("cameraUrls can not less than 2") | |||||
} | |||||
default: | |||||
return errors.New("unknown scene type:" + cmd.Scene) | |||||
} | |||||
if u, e := url.Parse(cmd.PushUrl); nil != e { | |||||
return errors.New("invalid pushUrl:" + e.Error()) | |||||
} else if u.Scheme != "http" && u.Scheme != "https" { | |||||
return errors.New("can not support pushUrl with " + u.Scheme) | |||||
} | |||||
return nil | |||||
switch cmd.Scene { | |||||
case "pullUp", "standJump", "sitUps": | |||||
if len(cmd.CameraUrls) < 1 { | |||||
return errors.New("cameraUrls can not less than 1") | |||||
} | |||||
case "race": | |||||
if len(cmd.CameraUrls) < 2 { | |||||
return errors.New("cameraUrls can not less than 2") | |||||
} | |||||
default: | |||||
return errors.New("unknown scene type:" + cmd.Scene) | |||||
} | |||||
if u, e := url.Parse(cmd.PushUrl); nil != e { | |||||
return errors.New("invalid pushUrl:" + e.Error()) | |||||
} else if u.Scheme != "http" && u.Scheme != "https" { | |||||
return errors.New("can not support pushUrl with " + u.Scheme) | |||||
} | |||||
return nil | |||||
} | } | ||||
func setScene(c *fiber.Ctx) error { | func setScene(c *fiber.Ctx) error { | ||||
var sceneCmd SceneCommand | |||||
if err := c.BodyParser(&sceneCmd); nil != err { | |||||
return failureResponse(c, "-1", err.Error(), 400) | |||||
} else if nil != currentScene { | |||||
return failureResponse(c, "1", "A working scene is started", 400) | |||||
} else if err = validateSceneCmd(sceneCmd); nil != err { | |||||
return failureResponse(c, "2", err.Error(), 400) | |||||
} else { | |||||
currentScene = &sceneCmd | |||||
return successResponse(c, "Updated successfully.") | |||||
} | |||||
var sceneCmd SceneCommand | |||||
if err := c.BodyParser(&sceneCmd); nil != err { | |||||
return failureResponse(c, "-1", err.Error(), 400) | |||||
} else if nil != currentScene { | |||||
return failureResponse(c, "1", "A working scene is started", 400) | |||||
} else if err = validateSceneCmd(sceneCmd); nil != err { | |||||
return failureResponse(c, "2", err.Error(), 400) | |||||
} else { | |||||
// currentScene = &sceneCmd | |||||
if e := sceneTaskProc(&sceneCmd); nil != e { | |||||
return failureResponse(c, "3", err.Error(), 409) | |||||
} else { | |||||
return successResponse(c, "Updated successfully.") | |||||
} | |||||
} | |||||
} | } | ||||
func stopScene(c *fiber.Ctx) error { | func stopScene(c *fiber.Ctx) error { | ||||
currentScene = nil | |||||
return successResponse(c, "Updated successfully.") | |||||
currentScene = nil | |||||
sceneStopChannel <- true | |||||
return successResponse(c, "Updated successfully.") | |||||
} | } | ||||
func getStatus(c *fiber.Ctx) error { | func getStatus(c *fiber.Ctx) error { | ||||
var scene = "" | |||||
var seq = 0 | |||||
if nil != currentScene { | |||||
scene = currentScene.Scene | |||||
} | |||||
if nil != currentTest { | |||||
seq = currentTest.SequenceId | |||||
} | |||||
return successResponseEx(c, "success", scene, seq) | |||||
var scene = "" | |||||
var seq int64 = 0 | |||||
if nil != currentScene { | |||||
scene = currentScene.Scene | |||||
} | |||||
if nil != currentTest { | |||||
seq = currentTest.SequenceId | |||||
} | |||||
return successResponseEx(c, "success", scene, seq) | |||||
} | |||||
func sceneTaskProc(cmd *SceneCommand) error { | |||||
var f func(int64) error = nil | |||||
switch cmd.Scene { | |||||
case "pullUp": | |||||
f = pullUpTask | |||||
case "standJump": | |||||
f = standJumpTask | |||||
case "sitUps": | |||||
f = sitUpsTask | |||||
case "race": | |||||
f = raceTask | |||||
default: | |||||
return errors.New("unknown scene type:" + cmd.Scene) | |||||
} | |||||
sceneStopChannel = make(chan bool) | |||||
var tk = time.NewTicker(time.Second * 3) | |||||
go func() { | |||||
defer func() { | |||||
tk.Stop() | |||||
close(sceneStopChannel) | |||||
sceneStopChannel = nil | |||||
}() | |||||
time.Sleep(time.Second) | |||||
currentScene = cmd | |||||
currentScene.proc = f | |||||
for { | |||||
select { | |||||
case <-tk.C: | |||||
log.Println(" ...") | |||||
case <-sceneStopChannel: | |||||
log.Println("Scene Stopping...") | |||||
return | |||||
} | |||||
} | |||||
}() | |||||
return nil | |||||
} | } | ||||
func init() { | func init() { | ||||
currentScene = nil | |||||
currentScene = nil | |||||
sceneStopChannel = nil | |||||
} | } |