zzf 1 год назад
Родитель
Сommit
1aaf58c789
12 измененных файлов с 330 добавлено и 171 удалено
  1. 62 22
      api/gateway.go
  2. 48 10
      api/sse.go
  3. 1 0
      config/application.yaml
  4. 1 0
      config/config.go
  5. 3 0
      constant/constant.go
  6. 5 6
      err/errMsg.go
  7. 1 9
      go.mod
  8. 3 58
      go.sum
  9. 24 31
      http/http.go
  10. 2 1
      initialize/router.go
  11. 180 0
      initialize/ws.go
  12. 0 34
      main.go

+ 62 - 22
api/gateway.go

@@ -3,7 +3,7 @@ package api
 import (
 	"confrontation-training/common"
 	"confrontation-training/constant"
-	errmsg "confrontation-training/err"
+	errors "confrontation-training/err"
 	"confrontation-training/global"
 	"confrontation-training/http"
 	"confrontation-training/models"
@@ -32,7 +32,7 @@ func ScanDevice(c *gin.Context) {
 	err := c.ShouldBindJSON(&param)
 	if err != nil {
 		fmt.Printf("参数格式化异常:%s", err.Error())
-		response.Failed(errmsg.ParamInvalid, c)
+		response.Failed(errors.ParamInvalid, c)
 		return
 	}
 	paramMap := make(map[string]string)
@@ -45,7 +45,7 @@ func ScanDevice(c *gin.Context) {
 		} else if param.FilterName == "1" {
 			paramMap["filter_name"] = constant.FilterNameECG
 		} else {
-			response.Failed(errmsg.ParamInvalid+":过滤类型-"+param.FilterName+"无效", c)
+			response.Failed(errors.ParamInvalid+":过滤类型-"+param.FilterName+"无效", c)
 			return
 		}
 	} else {
@@ -59,8 +59,9 @@ func ScanDevice(c *gin.Context) {
 	}
 	paramMap["active"] = "1"
 	paramMap["event"] = "1"
-	result := SseScanDevice(paramMap)
-	response.Success("扫描完成", result, c)
+	SseScanDevice(paramMap)
+	//http.GetReq(global.Config.Gateway.BaseUrl + global.Config.Gateway.OpenNotify)
+	response.Success("扫描完成", "", c)
 	return
 }
 
@@ -80,7 +81,7 @@ func ConnectDevice(c *gin.Context) {
 	err := c.ShouldBindJSON(&param)
 	if err != nil {
 		fmt.Printf("参数格式化异常:%s", err.Error())
-		response.Failed(errmsg.ParamInvalid, c)
+		response.Failed(errors.ParamInvalid, c)
 		return
 	}
 	jsonParam, err := json.Marshal(param)
@@ -98,15 +99,18 @@ func ConnectDevice(c *gin.Context) {
 	fmt.Println("response:", httpResponse.Header)
 	body, _ := ioutil.ReadAll(httpResponse.Body)
 	fmt.Println("response Body:", string(body))
-
-	if status == 200 {
-		//成功
-		response.Success(errmsg.DeviceConnectSuccess, nil, c)
-	} else {
-		//失败
-		response.Failed(errmsg.DeviceConnectError+string(body), c)
+	if status != 200 {
+		response.Failed(errors.DeviceConnectError+string(body), c)
+		return
 	}
-
+	httpResponse = http.GetReq(global.Config.Gateway.BaseUrl + global.Config.Gateway.OpenChannel)
+	if httpResponse.StatusCode != 200 {
+		fmt.Printf("%s:%s", errors.OpenChannelError, httpResponse.Body)
+		response.Failed(errors.OpenChannelError, c)
+		return
+	}
+	response.Success(errors.DeviceConnectSuccess, param.Mac, c)
+	return
 }
 
 // WriteData
@@ -125,7 +129,7 @@ func WriteData(c *gin.Context) {
 	err := c.ShouldBindJSON(&param)
 	if err != nil {
 		fmt.Printf("参数格式化异常:%s", err.Error())
-		response.Failed(errmsg.ParamInvalid, c)
+		response.Failed(errors.ParamInvalid, c)
 		return
 	}
 	userNameHex := hex.EncodeToString([]byte(param.UserName))
@@ -186,25 +190,61 @@ func WriteData(c *gin.Context) {
 	bindUserUrl = strings.Replace(bindUserUrl, "MAC", param.Mac, -1)
 	bindUserUrl = strings.Replace(bindUserUrl, "DATA", bindUserCmd, -1)
 	fmt.Println("bindUserUrl====" + bindUserUrl)
-	http.GetReq(bindUserUrl)
+	httpResponse := http.GetReq(bindUserUrl)
+	if httpResponse.StatusCode != 200 {
+		fmt.Printf("%s:%s", errors.SetDeviceTimeFailed, httpResponse.Body)
+		response.Failed(errors.SetDeviceTimeFailed, c)
+		return
+	}
 	//授时
 	setTimeUrl := fmt.Sprintf("%s%s", global.Config.Gateway.BaseUrl, global.Config.Gateway.WriteDataUrl)
 	setTimeUrl = strings.Replace(setTimeUrl, "MAC", param.Mac, -1)
 	setTimeUrl = strings.Replace(setTimeUrl, "DATA", setTimeCmd, -1)
-	http.GetReq(setTimeUrl)
+	httpResponse = http.GetReq(setTimeUrl)
+	if httpResponse.StatusCode != 200 {
+		fmt.Printf("%s:%s", errors.BindUserFailed, httpResponse.Body)
+		response.Failed(errors.BindUserFailed, c)
+		return
+	}
 	fmt.Println("setTimeUrl=====" + setTimeUrl)
 	//开始收集
 	startCollectUrl := fmt.Sprintf("%s%s", global.Config.Gateway.BaseUrl, global.Config.Gateway.WriteDataUrl)
 	startCollectUrl = strings.Replace(startCollectUrl, "MAC", param.Mac, -1)
 	startCollectUrl = strings.Replace(startCollectUrl, "DATA", startCollectCmd, -1)
 	fmt.Println("startCollectUrl=====" + startCollectUrl)
-	http.GetReq(startCollectUrl)
-
-	//开始收集指令
+	httpResponse = http.GetReq(startCollectUrl)
+	if httpResponse.StatusCode != 200 {
+		fmt.Printf("%s:%s", errors.StartCollocateFailed, httpResponse.Body)
+		response.Failed(errors.StartCollocateFailed, c)
+		return
+	}
+	//开始传输指令
 	startTransUrl := fmt.Sprintf("%s%s", global.Config.Gateway.BaseUrl, global.Config.Gateway.WriteDataUrl)
 	startTransUrl = strings.Replace(startTransUrl, "MAC", param.Mac, -1)
 	startTransUrl = strings.Replace(startTransUrl, "DATA", constant.StartTransCmd, -1)
 	fmt.Println("startTransUrl====" + startTransUrl)
-	http.GetReq(startTransUrl)
-	response.Success(errmsg.WriteDataSuccess, nil, c)
+	httpResponse = http.GetReq(startTransUrl)
+	if httpResponse.StatusCode != 200 {
+		fmt.Printf("%s:%s", errors.StartTransFailed, httpResponse.Body)
+		response.Failed(errors.StartTransFailed, c)
+		return
+	}
+	response.Success(errors.WriteDataSuccess, nil, c)
+	return
+}
+
+// OpenNotify
+// PingExample confrontation-training
+// @Summary 开启数据通知
+// @Schemes
+// @Description 开启数据通知
+// @Tags 设备管理
+// @Accept json
+// @Produce json
+// @Success 200 {string} string "ok"
+// @Router /v1/device/open/notify/ [get]
+func OpenNotify(c *gin.Context) {
+	SseOpenNotify()
+	response.Success("开启通知", "", c)
+	return
 }

+ 48 - 10
api/sse.go

@@ -1,17 +1,26 @@
 package api
 
 import (
+	"confrontation-training/constant"
+	errmsg "confrontation-training/err"
 	"confrontation-training/global"
 	"confrontation-training/models"
 	"encoding/json"
 	"fmt"
+	"github.com/gorilla/websocket"
 	"github.com/r3labs/sse/v2"
+	"strings"
 	"time"
 )
 
 // SseScanDevice 扫描设备
-func SseScanDevice(paramMap map[string]string) map[string]models.DeviceScanned {
+func SseScanDevice(paramMap map[string]string) {
 	var scanUrl = global.Config.Gateway.BaseUrl + global.Config.Gateway.ScanUrl
+	ws, _, err := websocket.DefaultDialer.Dial(global.Config.Websocket.WSUrl, nil)
+	if err != nil {
+		fmt.Println("Websocket client init error" + err.Error())
+		return
+	}
 	deviceMap := make(map[string]models.DeviceScanned)
 	if len(paramMap) > 0 {
 		for key, value := range paramMap {
@@ -20,6 +29,7 @@ func SseScanDevice(paramMap map[string]string) map[string]models.DeviceScanned {
 	}
 	client := sse.NewClient(scanUrl)
 	go func() {
+
 		fmt.Println("开始SSE")
 		err := client.SubscribeRaw(func(msg *sse.Event) {
 			//fmt.Println(string(msg.Data))
@@ -38,29 +48,57 @@ func SseScanDevice(paramMap map[string]string) map[string]models.DeviceScanned {
 			deviceMap[deviceScanned.MAC] = deviceScanned
 			fmt.Println(deviceScanned)
 		})
-
 		if err != nil {
 			fmt.Println(err.Error())
 			return
 		}
 	}()
-	timer := time.NewTimer(time.Duration(global.Config.Gateway.ScanSecond) * time.Second)
-	events := make(chan *sse.Event)
+
+	if err != nil {
+		fmt.Println(err.Error())
+		return
+	}
+	timer := time.NewTimer(time.Duration(global.Config.Gateway.ScanSecond) * time.Millisecond)
 	select {
 	case <-timer.C:
-		fmt.Println("关闭SSE:" + (time.Now()).String())
-		client.Unsubscribe(events)
-		timer.Stop()
+		messageMap := make(map[string]map[string]models.DeviceScanned)
+		messageMap[constant.MessageTypeDeviceScanned] = deviceMap
+		bytes, err := json.Marshal(messageMap)
+		if err != nil {
+			fmt.Printf("json异常:%s", err.Error())
+			return
+		}
+		err = ws.WriteMessage(websocket.TextMessage, bytes)
+		if err != nil {
+			return
+		}
 	}
-	return deviceMap
 }
 
 // SseOpenNotify 开启通知
 func SseOpenNotify() {
 	var notifyUrl = global.Config.Gateway.BaseUrl + global.Config.Gateway.NotifyUrl
-	client := sse.NewClient(notifyUrl)
-	err := client.SubscribeRaw(func(msg *sse.Event) {
 
+	ws, _, err := websocket.DefaultDialer.Dial(global.Config.Websocket.WSUrl, nil)
+	if err != nil {
+		fmt.Println("Websocket client init error" + err.Error())
+		return
+	}
+	client := sse.NewClient(notifyUrl)
+	err = client.SubscribeRaw(func(msg *sse.Event) {
+		s := string(msg.Data)
+		fmt.Println("notify receive data :" + s)
+		flag := strings.HasPrefix(s, "E840") || strings.HasPrefix(s, "E841") || strings.HasPrefix(s, "E823")
+		if !flag {
+			//websocket 通知数据
+			//msgMap := make(map[string]string)
+			//msgMap[]
+			err := ws.WriteMessage(websocket.TextMessage, msg.Data)
+			if err != nil {
+				fmt.Println(errmsg.SendMessageError + err.Error())
+				return
+			}
+		}
 	})
 	if err != nil {
 		return

+ 1 - 0
config/application.yaml

@@ -29,6 +29,7 @@ gateway:
   connUrl: /gap/nodes/MAC/connection?chip
   notifyUrl: /gatt/nodes?event=1
   writeDataUrl: /gatt/nodes/MAC/handle/39/value/DATA
+  openChannel: /gate/nodes/MAC/handle/36/value/0100
   scanSecond: 30 #蓝牙扫描时长
 
 

+ 1 - 0
config/config.go

@@ -8,6 +8,7 @@ type Gateway struct {
 	NotifyUrl       string `mapstructure:"notifyUrl"`
 	WriteDataUrl    string `mapstructure:"writeDataUrl"`
 	StartCollectUrl string `mapstructure:"startCollectUrl"`
+	OpenChannel     string `mapstructure:"openChannel"`
 }
 
 type Config struct {

+ 3 - 0
constant/constant.go

@@ -17,4 +17,7 @@ const (
 	EcgDefaultWeight   = 65
 	MaxNameByteLength  = 12
 	DefaultPlaceHolder = "00"
+	// MessageTypeDeviceScanned websocket 消息类型 扫描到设备
+	MessageTypeDeviceScanned = "device"
+	MessageTypeData          = "data"
 )

+ 5 - 6
err/errMsg.go

@@ -14,15 +14,14 @@ const (
 	UserPasswordChangeSuccess = "用户密码修改成功"
 	UserPasswordChangeError   = "用户密码修改失败"
 	UserOldPasswordError      = "用户原密码错误"
-	FileExtendNameError       = "文件类型不符"
-	FileUploadError           = "文件上传失败"
-	JSONParseError            = "JSON 转换异常"
 	SendMessageError          = "消息发送失败"
 	SocketCloseError          = "Socket关闭异常:"
-	RecordSaveError           = "记录保存失败"
 	DeviceConnectSuccess      = "设备连接成功"
 	WriteDataSuccess          = "写入数据成功"
 	DeviceConnectError        = "设备连接失败"
-	TestResultFailed          = "测试失败,失败原因:"
-	TestResultSuccess         = "测试完成,测试结果:"
+	OpenChannelError          = "打开设备通道失败"
+	SetDeviceTimeFailed       = "授时指令发送失败"
+	BindUserFailed            = "绑定用户指令发送失败"
+	StartCollocateFailed      = "开始收集指令发送失败"
+	StartTransFailed          = "开始传送指令发送失败"
 )

+ 1 - 9
go.mod

@@ -6,6 +6,7 @@ require (
 	github.com/gin-gonic/gin v1.9.1
 	github.com/golang-jwt/jwt v3.2.2+incompatible
 	github.com/google/uuid v1.1.2
+	github.com/gorilla/websocket v1.5.0
 	github.com/r3labs/sse/v2 v2.10.0
 	github.com/spf13/viper v1.16.0
 	github.com/swaggo/files v1.0.1
@@ -16,12 +17,9 @@ require (
 
 require (
 	github.com/KyleBanks/depth v1.2.1 // indirect
-	github.com/PuerkitoBio/purell v1.2.0 // indirect
-	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
 	github.com/bytedance/sonic v1.10.0-rc3 // indirect
 	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
 	github.com/chenzhuoyu/iasm v0.9.0 // indirect
-	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
@@ -48,8 +46,6 @@ require (
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.9 // indirect
-	github.com/russross/blackfriday/v2 v2.1.0 // indirect
-	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
 	github.com/spf13/afero v1.9.5 // indirect
 	github.com/spf13/cast v1.5.1 // indirect
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
@@ -58,8 +54,6 @@ require (
 	github.com/swaggo/swag v1.16.1 // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
 	github.com/ugorji/go/codec v1.2.11 // indirect
-	github.com/urfave/cli/v2 v2.25.7 // indirect
-	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
 	golang.org/x/arch v0.4.0 // indirect
 	golang.org/x/crypto v0.11.0 // indirect
 	golang.org/x/net v0.12.0 // indirect
@@ -69,7 +63,5 @@ require (
 	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	sigs.k8s.io/yaml v1.3.0 // indirect
 )

+ 3 - 58
go.sum

@@ -40,21 +40,12 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
 github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
-github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
-github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/purell v1.2.0 h1:/Jdm5QfyM8zdlqT6WVZU4cfP23sot6CEHA4CS49Ezig=
-github.com/PuerkitoBio/purell v1.2.0/go.mod h1:OhLRTaaIzhvIyofkJfB24gokC7tM42Px5UhoT32THBk=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
 github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
-github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
-github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
 github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
 github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0=
 github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
-github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
 github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
 github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
@@ -67,8 +58,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -93,22 +82,16 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
 github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
 github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
 github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
 github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
-github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
-github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
 github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
 github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
 github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
-github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
-github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
 github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
 github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
 github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
 github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
 github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
 github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
@@ -118,8 +101,6 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
 github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
 github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
 github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
-github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
-github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
 github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
 github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
@@ -185,6 +166,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -203,8 +186,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
-github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
-github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
 github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
 github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
@@ -222,7 +203,6 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
 github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
@@ -237,10 +217,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
-github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
 github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -252,10 +229,6 @@ github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0=
 github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
-github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
 github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
 github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
@@ -279,8 +252,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
-github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
@@ -289,18 +260,12 @@ github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
 github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
 github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
 github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
-github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w=
-github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its=
 github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
 github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
 github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
 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/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
-github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
 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=
@@ -313,8 +278,6 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
-golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
-golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc=
 golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -325,8 +288,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
-golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
 golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -363,7 +324,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
 golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -397,12 +357,9 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY
 golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
 golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -457,18 +414,14 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
 golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -483,8 +436,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
 golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -538,8 +489,6 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
-golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
 golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
 golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -635,16 +584,14 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
 google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
 google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
 gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
@@ -672,5 +619,3 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
-sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

+ 24 - 31
http/http.go

@@ -7,53 +7,46 @@ import (
 	"io"
 	"io/ioutil"
 	"net/http"
-	"strings"
 	"unsafe"
 )
 
-func GetReq(url string) map[string]string {
+func GetReq(url string) *http.Response {
 	client := &http.Client{}
 
 	req, err := http.NewRequest("GET", url, nil)
 	if err != nil {
 		panic(err)
 	}
-
 	resp, err := client.Do(req)
-
-	defer resp.Body.Close()
-
-	body, err := ioutil.ReadAll(resp.Body)
 	if err != nil {
 		panic(err)
 	}
-	var resData map[string]string
-	err = json.Unmarshal(body, &resData)
-	if err != nil {
-		fmt.Println("body===" + string(body))
-		return nil
-	} else {
-		return resData
-	}
+	defer func(Body io.ReadCloser) {
+		err := Body.Close()
+		if err != nil {
+			fmt.Print("Body close err" + err.Error())
+		}
+	}(resp.Body)
+	return resp
 
 }
 
-func postReq(name string, age int) {
-	client := &http.Client{}
-
-	req, err := http.NewRequest("POST", "http://localhost:5000/post",
-		strings.NewReader(fmt.Sprintf("name=%s&age=%d", name, age)))
-	if err != nil {
-		panic(err)
-	}
-
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-
-	resp, err := client.Do(req)
-
-	defer resp.Body.Close()
-
-}
+//func postReq(name string, age int) {
+//	client := &http.Client{}
+//
+//	req, err := http.NewRequest("POST", "http://localhost:5000/post",
+//		strings.NewReader(fmt.Sprintf("name=%s&age=%d", name, age)))
+//	if err != nil {
+//		panic(err)
+//	}
+//
+//	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+//
+//	resp, err := client.Do(req)
+//
+//	defer resp.Body.Close()
+//
+//}
 
 // PostReqJson 通过json提交post
 func PostReqJson(url string, json []byte) *http.Response {

+ 2 - 1
initialize/router.go

@@ -26,7 +26,7 @@ func Router() {
 	//swag
 	engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
 	engine.Static("/file", "./files")
-	//engine.GET("/ws", WsHandler)
+	engine.GET("/ws", WsHandler)
 
 	//group
 	v1 := engine.Group("/v1")
@@ -42,6 +42,7 @@ func Router() {
 	device.GET("/scan", api.ScanDevice)
 	device.GET("/connection", api.ConnectDevice)
 	device.POST("/write/data/", api.WriteData)
+	device.GET("/open/notify/", api.OpenNotify)
 	//
 	//record := v1.Group("/record")
 	//record.POST("/create", api.GetRecord().SaveRecord)

+ 180 - 0
initialize/ws.go

@@ -0,0 +1,180 @@
+package initialize
+
+import (
+	errmsg "confrontation-training/err"
+	"encoding/json"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/gorilla/websocket"
+	"log"
+	"net/http"
+)
+
+// ClientManager is a websocket manager
+type ClientManager struct {
+	Clients    map[string]*Client
+	Broadcast  chan []byte
+	Register   chan *Client
+	Unregister chan *Client
+}
+
+// Client is a websocket client
+type Client struct {
+	ID     string
+	Socket *websocket.Conn
+	Send   chan []byte
+}
+
+// Message is return msg
+type Message struct {
+	Sender    string `json:"sender,omitempty"`
+	Recipient string `json:"recipient,omitempty"`
+	Content   string `json:"content,omitempty"`
+	RecordId  string `json:"recordId,omitempty"`
+	Status    bool   `json:"status,omitempty"`
+}
+
+// Manager define a ws server manager
+var Manager = ClientManager{
+	Broadcast:  make(chan []byte),
+	Register:   make(chan *Client),
+	Unregister: make(chan *Client),
+	Clients:    make(map[string]*Client),
+}
+
+// Start is  项目运行前, 协程开启start -> go Manager.Start()
+func (manager *ClientManager) Start() {
+	for {
+		log.Println("<---管道通信--->")
+		select {
+		case conn := <-Manager.Register:
+			log.Printf("新用户加入:%v", conn.ID)
+			Manager.Clients[conn.ID] = conn
+			//jsonMessage, _ := json.Marshal(&Message{Content: "Successful connection to socket service"})
+			//conn.Send <- jsonMessage
+		case conn := <-Manager.Unregister:
+			//log.Printf("用户离开:%v", conn.ID)
+			if _, ok := Manager.Clients[conn.ID]; ok {
+				//jsonMessage, _ := json.Marshal(&Message{Content: "A socket has disconnected"})
+				//conn.Send <- jsonMessage
+				close(conn.Send)
+				delete(Manager.Clients, conn.ID)
+			}
+		case message := <-Manager.Broadcast:
+			MessageStruct := Message{}
+			err := json.Unmarshal(message, &MessageStruct)
+			if err != nil {
+				return
+			}
+			for id, conn := range Manager.Clients {
+
+				//处理结果回执消息
+				if MessageStruct.Recipient == "server" {
+					//更新record
+					if MessageStruct.RecordId != "" {
+
+						//content := ""
+						if MessageStruct.Status {
+							//content = errmsg.TestResultSuccess + MessageStruct.Content
+						} else {
+							//content = errmsg.TestResultFailed + MessageStruct.Content
+						}
+						//recordService.UpdateRecordById(MessageStruct.RecordId, content)
+					}
+
+				} else {
+					if id == creatId(MessageStruct.Recipient, MessageStruct.Sender) {
+						continue
+					}
+					select {
+					case conn.Send <- message:
+					default:
+						close(conn.Send)
+						delete(Manager.Clients, conn.ID)
+					}
+				}
+
+			}
+		}
+	}
+}
+func creatId(uid, touid string) string {
+	return uid + "_" + touid
+}
+func (c *Client) Read() {
+	defer func() {
+		Manager.Unregister <- c
+		err := c.Socket.Close()
+		if err != nil {
+			fmt.Println(errmsg.SocketCloseError + err.Error())
+			return
+		}
+	}()
+
+	for {
+		c.Socket.PongHandler()
+		_, message, err := c.Socket.ReadMessage()
+		if err != nil {
+			Manager.Unregister <- c
+			err := c.Socket.Close()
+			if err != nil {
+				fmt.Println(errmsg.SocketCloseError + err.Error())
+				return
+			}
+			break
+		}
+		log.Printf("读取到客户端的信息:%s", string(message))
+		Manager.Broadcast <- message
+	}
+}
+
+func (c *Client) Write() {
+	defer func() {
+		err := c.Socket.Close()
+		if err != nil {
+			fmt.Println(errmsg.SocketCloseError + err.Error())
+			return
+		}
+	}()
+
+	for {
+		select {
+		case message, ok := <-c.Send:
+			if !ok {
+				err := c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
+				if err != nil {
+					fmt.Println("socket writeMessage error :" + err.Error())
+					return
+				}
+				return
+			}
+			log.Printf("发送到到客户端的信息:%s", string(message))
+
+			err := c.Socket.WriteMessage(websocket.TextMessage, message)
+			if err != nil {
+				fmt.Println("socket writeMessage error :" + err.Error())
+				return
+			}
+		}
+	}
+}
+
+// WsHandler TestHandler socket 连接 中间件 作用:升级协议,用户验证,自定义信息等
+func WsHandler(c *gin.Context) {
+	uid := c.Query("uid")
+	touid := c.Query("to_uid")
+	conn, err := (&websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}).Upgrade(c.Writer, c.Request, nil)
+	if err != nil {
+		http.NotFound(c.Writer, c.Request)
+		return
+	}
+	//可以添加用户信息验证
+	client := &Client{
+		ID:     creatId(uid, touid),
+		Socket: conn,
+		Send:   make(chan []byte),
+	}
+	Manager.Register <- client
+	go client.Read()
+	go client.Write()
+}

+ 0 - 34
main.go

@@ -10,38 +10,4 @@ import "confrontation-training/initialize"
 //contact.url https://www.cnblogs.com/wormworm
 func main() {
 	initialize.Run()
-	//aa()
-}
-
-func aa() {
-	//parse, err := time.Parse(`2006-01-02 15:04:05`, "2023-07-31 14:28:00")
-	//if err != nil {
-	//	return ""
-	//}
-	//fmt.Println(parse)
-	//year := parse.Year()
-	//monthStr := parse.Format("01")
-	//month, err := strconv.ParseInt(monthStr, 10, 64)
-	//if err != nil {
-	//	return ""
-	//}
-	//day := parse.Day()
-	//hour := parse.Hour()
-	//minute := parse.Minute()
-	//second := parse.Second()
-	//return strconv.FormatInt(23, 16) +
-	//	strconv.FormatInt(07, 16) +
-	//	strconv.FormatInt(int64(31), 16) +
-	//	strconv.FormatInt(int64(14), 16) +
-	//	strconv.FormatInt(int64(28), 16) +
-	//	strconv.FormatInt(int64(00), 16)
-	//i := int64(23)
-	//var str strings.Builder
-	//if i < 10 {
-	//	str.WriteString("0")
-	//	str.WriteString(strconv.FormatInt(i, 16))
-	//} else {
-	//	str.WriteString(strconv.FormatInt(23, 16))
-	//}
-	//fmt.Println(str.String())
 }