diff --git a/api/publishedGi.go b/api/publishedGi.go index b047278..0915b03 100644 --- a/api/publishedGi.go +++ b/api/publishedGi.go @@ -31,6 +31,7 @@ func InitPublishedGiRouter(api *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddl // @Tags 发布的图形数据Api // @Accept json // @Produce json +// @Param Authorization header string true "JWT Token" // @Param pagePublishedGiReqDto query dto.PublishedGiReqDto true "分页查询参数" // @Success 200 {object} dto.PageDto // @Failure 401 {object} dto.ErrorDto @@ -63,7 +64,7 @@ func pageQueryPublishedGi(c *gin.Context) { // @Tags 发布的图形数据Api // @Accept json // @Produce json -// @Param token query string true "JWT Token" +// @Param Authorization header string true "JWT Token" // @Param pagePublishedGiReqDto query dto.PublishedGiReqDto true "查询参数" // @Success 200 {object} []model.PublishedGi // @Failure 401 {object} dto.ErrorDto @@ -95,6 +96,7 @@ func listQueryPublishedGi(c *gin.Context) { // @Tags 发布的图形数据Api // @Accept json // @Produce json +// @Param Authorization header string true "JWT Token" // @Param PublishReqDto query dto.PublishReqDto true "查询参数" // @Success 200 {object} nil // @Failure 401 {object} dto.ErrorDto @@ -122,6 +124,7 @@ func publishFromDraft(c *gin.Context) { // @Tags 发布的图形数据Api // @Accept json // @Produce json +// @Param Authorization header string true "JWT Token" // @Param id path int true "id" // @Success 200 {object} model.PublishedGi // @Failure 401 {object} dto.ErrorDto @@ -154,6 +157,7 @@ func getPublishedGiById(c *gin.Context) { // @Tags 发布的图形数据Api // @Accept json // @Produce json +// @Param Authorization header string true "JWT Token" // @Param id path int true "id" // @Success 200 {object} nil // @Failure 401 {object} dto.ErrorDto diff --git a/config/config.go b/config/config.go index df89e83..bdef266 100644 --- a/config/config.go +++ b/config/config.go @@ -13,6 +13,7 @@ type AppConfig struct { Datasource datasource Logging log Messaging messaging + Dynamics dynamics } type server struct { Port int @@ -31,6 +32,7 @@ type log struct { Compress bool // 是否压缩日志 Stdout bool // 是否输出到控制台 } +<<<<<<< HEAD type messaging struct { Centrifugo centrifugo } @@ -39,6 +41,11 @@ type centrifugo struct { ApiKey string ApiEndpoint string Address string +======= +type dynamics struct { + UdpLocalPort int + UdpRemoteAddr string +>>>>>>> a435ec7520b6fab654c7e0b9ece87920ee534ba9 } var Config AppConfig diff --git a/docs/docs.go b/docs/docs.go index ad319c2..8ebdb73 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -343,8 +343,8 @@ const docTemplate = `{ { "type": "string", "description": "JWT Token", - "name": "token", - "in": "query", + "name": "Authorization", + "in": "header", "required": true }, { diff --git a/docs/swagger.json b/docs/swagger.json index 352ee80..78cdaa6 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -336,8 +336,8 @@ { "type": "string", "description": "JWT Token", - "name": "token", - "in": "query", + "name": "Authorization", + "in": "header", "required": true }, { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 22a72fd..d277b45 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -376,8 +376,8 @@ paths: description: 可以通过名称过滤 parameters: - description: JWT Token - in: query - name: token + in: header + name: Authorization required: true type: string - in: query diff --git a/dynamics/example.go b/dynamics/example.go new file mode 100644 index 0000000..e34d28a --- /dev/null +++ b/dynamics/example.go @@ -0,0 +1,8 @@ +package dynamics + +// 该包下函数的使用示例 +func example() { + RunUdpServer() //启动udp服务 + _ = SendTurnoutInfo(nil) //发送道岔状态 + _ = SendTrainInitReq(nil) //发送列车初始化请求 +} diff --git a/dynamics/http.go b/dynamics/http.go new file mode 100644 index 0000000..97127a6 --- /dev/null +++ b/dynamics/http.go @@ -0,0 +1,22 @@ +package dynamics + +import ( + "bytes" + "encoding/json" + "errors" + "net/http" + "strconv" +) + +func SendTrainInitReq(info *InitTrainInfo) error { + ip := "127.0.0.1" + uri := "/api/aerodynamics/init/train" + url := "http://" + ip + uri + + data, _ := json.Marshal(info) + resp, _ := http.Post(url, "application/json", bytes.NewBuffer(data)) + if resp.StatusCode != http.StatusOK { + return errors.New("响应的http状态码:" + strconv.Itoa(resp.StatusCode)) + } + return resp.Body.Close() +} diff --git a/dynamics/httpData.go b/dynamics/httpData.go new file mode 100644 index 0000000..81b45ad --- /dev/null +++ b/dynamics/httpData.go @@ -0,0 +1,9 @@ +package dynamics + +type InitTrainInfo struct { + TrainIndex uint16 + LinkIndex uint16 + LinkOffset uint16 + Speed uint16 + Up bool +} diff --git a/dynamics/udp.go b/dynamics/udp.go new file mode 100644 index 0000000..97b0303 --- /dev/null +++ b/dynamics/udp.go @@ -0,0 +1,89 @@ +package dynamics + +import ( + "encoding/binary" + "errors" + "fmt" + "github.com/panjf2000/gnet/v2" + "joylink.club/bj-rtsts-server/config" + "log" + "net" +) + +var server *udpServer + +// SendTurnoutInfo 发送道岔信息 +func SendTurnoutInfo(info *TurnoutInfo) error { + if server == nil { + return errors.New("服务尚未启动") + } + remoteAddr, _ := net.ResolveUDPAddr("udp", config.Config.Dynamics.UdpRemoteAddr) + conn, err := net.DialUDP("udp", nil, remoteAddr) + if err != nil { + panic(err) + } + defer conn.Close() + var data []byte + data = binary.BigEndian.AppendUint16(data, info.Code) + var b byte + if info.NPosition { + b |= 1 << 7 + } + if info.RPosition { + b |= 1 << 6 + } + data = append(data, b) + _, err = conn.Write(data) + + return err +} + +type udpServer struct { + gnet.BuiltinEventEngine + + eng gnet.Engine + addr string + multicore bool + + eventHandlers []gnet.EventHandler +} + +func (server *udpServer) OnBoot(eng gnet.Engine) gnet.Action { + server.eng = eng + log.Printf("echo server with multi-core=%t is listening on %s\n", server.multicore, server.addr) + return gnet.None +} + +// OnTraffic 接收到数据后的解析 +func (server *udpServer) OnTraffic(c gnet.Conn) gnet.Action { + buf, _ := c.Next(-1) + trainInfo := TrainInfo{} + trainInfo.LifeSignal = binary.BigEndian.Uint16(buf[0:2]) + trainInfo.Number = buf[2] + trainInfo.Len = binary.BigEndian.Uint16(buf[3:5]) + trainInfo.Link = buf[5] + trainInfo.LinkOffset = binary.BigEndian.Uint32(buf[6:10]) + trainInfo.Slope = buf[10] + b := buf[11] + trainInfo.UpSlope = (b & (1 << 7)) != 0 + trainInfo.Up = (b & (1 << 6)) != 0 + trainInfo.TotalResistance = binary.BigEndian.Uint16(buf[13:15]) + trainInfo.Resistance1 = binary.BigEndian.Uint16(buf[15:17]) + trainInfo.Resistance2 = binary.BigEndian.Uint16(buf[17:19]) + trainInfo.Resistance3 = binary.BigEndian.Uint16(buf[19:21]) + trainInfo.Speed = binary.BigEndian.Uint16(buf[21:23]) + trainInfo.HeadSpeed1 = binary.BigEndian.Uint16(buf[23:25]) + trainInfo.HeadSpeed2 = binary.BigEndian.Uint16(buf[25:27]) + trainInfo.TailSpeed1 = binary.BigEndian.Uint16(buf[27:29]) + trainInfo.TailSpeed2 = binary.BigEndian.Uint16(buf[29:31]) + trainInfo.HeadRadarSpeed = binary.BigEndian.Uint16(buf[31:33]) + trainInfo.TailRadarSpeed = binary.BigEndian.Uint16(buf[33:35]) + fmt.Println(trainInfo) + + return gnet.None +} + +func RunUdpServer() { + server = &udpServer{addr: fmt.Sprintf("udp://:%d", config.Config.Dynamics.UdpLocalPort), multicore: false} + log.Fatal(gnet.Run(server, server.addr, gnet.WithMulticore(server.multicore))) +} diff --git a/dynamics/udpData.go b/dynamics/udpData.go new file mode 100644 index 0000000..ecaa93d --- /dev/null +++ b/dynamics/udpData.go @@ -0,0 +1,48 @@ +package dynamics + +type TurnoutInfo struct { + Code uint16 + NPosition bool + RPosition bool +} + +type TrainInfo struct { + //生命信号 + LifeSignal uint16 + //列车号(车辆) + Number uint8 + //列车长度 + Len uint16 + //列车所在轨道link + Link uint8 + //列车所在link偏移量(cm) + LinkOffset uint32 + //列车所在位置坡度值(‰) + Slope uint8 + //列车所在位置坡度走势(上/下坡) + UpSlope bool + //列车当前运行方向(上/下行) + Up bool + //实际运行阻力(总)(KN) + TotalResistance uint16 + //阻力1(空气阻力)(KN) + Resistance1 uint16 + //阻力2(坡道阻力)(KN) + Resistance2 uint16 + //阻力3(曲线阻力)(KN) + Resistance3 uint16 + //列车运行速度(km/h) + Speed uint16 + //头车速传1速度值(km/h) + HeadSpeed1 uint16 + //头车速度2速度值 + HeadSpeed2 uint16 + //尾车速传1速度值 + TailSpeed1 uint16 + //尾车速度2速度值 + TailSpeed2 uint16 + //头车雷达速度值 + HeadRadarSpeed uint16 + //尾车雷达速度值 + TailRadarSpeed uint16 +} diff --git a/go.mod b/go.mod index 8dee683..cbdc6f4 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( github.com/appleboy/gin-jwt/v2 v2.9.1 github.com/gin-contrib/zap v0.1.0 + github.com/panjf2000/gnet/v2 v2.3.1 github.com/spf13/viper v1.16.0 github.com/swaggo/files v1.0.1 github.com/swaggo/swag v1.16.1 @@ -29,11 +30,13 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect go.opentelemetry.io/otel v1.10.0 // indirect go.opentelemetry.io/otel/trace v1.10.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/mod v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect golang.org/x/tools v0.11.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index fea2fa8..4dcc92e 100644 --- a/go.sum +++ b/go.sum @@ -254,6 +254,9 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/panjf2000/ants/v2 v2.8.1 h1:C+n/f++aiW8kHCExKlpX6X+okmxKXP7DWLutxuAPuwQ= +github.com/panjf2000/gnet/v2 v2.3.1 h1:J7vHkNxwsevVIw3u/6LCXgcnpGBk5iKqhQ2RMblGodc= +github.com/panjf2000/gnet/v2 v2.3.1/go.mod h1:Ik5lTy2nmBg9Uvjfcf2KRYs+EXVNOLyxPHpFOFlqu+M= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= @@ -315,6 +318,8 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -455,6 +460,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/xiannccda.setting.yml b/xiannccda.setting.yml index 7b2ba9e..13b4b1f 100644 --- a/xiannccda.setting.yml +++ b/xiannccda.setting.yml @@ -4,6 +4,11 @@ env: dev server: # 服务端口 port: 8080 +# 动力学端口配置 +dynamics: + udpLocalPort: 4000 + udpRemoteAddr: 127.0.0.1:3000 + # 数据源 datasource: # 数据库访问url