package trade import ( "errors" "mtp20access/client" "mtp20access/global" "mtp20access/model/common/response" "mtp20access/utils" "net/http" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "go.uber.org/zap" ) // TradeConn 终端连接WebSocket func TradeConn(c *gin.Context) (err error) { // 获取请求账号信息 // s, exists := c.Get("claims") // if !exists { // err = errors.New("获取请求账号信息异常") // global.M2A_LOG.Error(err.Error()) // return // } // claims := s.(*commonRequest.CustomClaims) // 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录 token := c.Request.Header.Get("Sec-WebSocket-Protocol") if token == "" { response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c) c.Abort() return } j := utils.NewJWT() // parseToken 解析token包含的信息 claims, err := j.ParseToken(token) if err != nil { if err == utils.ErrTokenExpired { response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_EXPIRED, "授权已过期", c) // c.Abort() return } response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c) // c.Abort() return } // 从Redis获取登录信息 loginMap, err := j.GetRedisLogin(claims.LoginID, claims.Group) if err != nil { response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_OTHER_LOGIN, "您的帐户异地登陆或令牌失效", c) // c.Abort() return } // 判断Token是否有效 if redisToken, isHas := loginMap["token"]; isHas { if redisToken != token { response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_OTHER_LOGIN, "您的帐户异地登陆或令牌失效", c) // c.Abort() return } } else { response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c) // c.Abort() return } // 获取登录账户信息 client, exists := client.Clients[claims.SessionID] if !exists { err = errors.New("获取登录账户信息异常") global.M2A_LOG.Error(err.Error()) return } // 需要注意的是,如果前端通过websocket连接时指定了Sec-WebSocket-Protocol,后端接收到连接后,必须原封不动的将Sec-WebSocket-Protocol头信息返回给前端,否则连接会抛出异常。 // c.Header("Sec-WebSocket-Protocol", token) // c.String(200, "ok") // 将http连接升级为websocket连接 upGrader := websocket.Upgrader{ ReadBufferSize: 1000000, WriteBufferSize: 1000000, CheckOrigin: func(r *http.Request) bool { return true }, //将获取的参数放进这个数组 Subprotocols: []string{token}, } ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) if err != nil { err = errors.New("连接错误") global.M2A_LOG.Error("将http连接升级为websocket连接失败", zap.Any("err", err)) return } client.SetTradeWebSocket(ws) return }