quote.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package quote
  2. import (
  3. "errors"
  4. "mtp20access/client"
  5. "mtp20access/global"
  6. commonRequest "mtp20access/model/common/request"
  7. "mtp20access/model/common/response"
  8. "mtp20access/model/quote/request"
  9. "mtp20access/utils"
  10. "net/http"
  11. "github.com/gin-gonic/gin"
  12. "github.com/gorilla/websocket"
  13. "go.uber.org/zap"
  14. )
  15. // QuoteConn 终端连接WebSocket
  16. func QuoteConn(c *gin.Context) (err error) {
  17. // 获取请求账号信息
  18. // s, exists := c.Get("claims")
  19. // if !exists {
  20. // err = errors.New("获取请求账号信息异常")
  21. // global.M2A_LOG.Error(err.Error())
  22. // return
  23. // }
  24. // claims := s.(*commonRequest.CustomClaims)
  25. // 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
  26. token := c.Request.Header.Get("Sec-WebSocket-Protocol")
  27. if token == "" {
  28. response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
  29. c.Abort()
  30. return
  31. }
  32. j := utils.NewJWT()
  33. // parseToken 解析token包含的信息
  34. claims, err := j.ParseToken(token)
  35. if err != nil {
  36. if err == utils.ErrTokenExpired {
  37. response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_EXPIRED, "授权已过期", c)
  38. // c.Abort()
  39. return
  40. }
  41. response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
  42. // c.Abort()
  43. return
  44. }
  45. // 从Redis获取登录信息
  46. loginMap, err := j.GetRedisLogin(claims.LoginID, claims.Group)
  47. if err != nil {
  48. response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_OTHER_LOGIN, "您的帐户异地登陆或令牌失效", c)
  49. // c.Abort()
  50. return
  51. }
  52. // 判断Token是否有效
  53. if redisToken, isHas := loginMap["token"]; isHas {
  54. if redisToken != token {
  55. response.FailWithCodeAndDetail(gin.H{"reload": true}, response.ERROR_TOKEN_OTHER_LOGIN, "您的帐户异地登陆或令牌失效", c)
  56. // c.Abort()
  57. return
  58. }
  59. } else {
  60. response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
  61. // c.Abort()
  62. return
  63. }
  64. // 获取登录账户信息
  65. client, exists := client.Clients[claims.SessionID]
  66. if !exists {
  67. err = errors.New("获取登录账户信息异常")
  68. global.M2A_LOG.Error(err.Error())
  69. return
  70. }
  71. // 需要注意的是,如果前端通过websocket连接时指定了Sec-WebSocket-Protocol,后端接收到连接后,必须原封不动的将Sec-WebSocket-Protocol头信息返回给前端,否则连接会抛出异常。
  72. // c.Header("Sec-WebSocket-Protocol", token)
  73. // c.String(200, "ok")
  74. // 将http连接升级为websocket连接
  75. upGrader := websocket.Upgrader{
  76. ReadBufferSize: 1000000,
  77. WriteBufferSize: 1000000,
  78. CheckOrigin: func(r *http.Request) bool {
  79. return true
  80. },
  81. //将获取的参数放进这个数组
  82. Subprotocols: []string{token},
  83. }
  84. ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
  85. if err != nil {
  86. err = errors.New("连接错误")
  87. global.M2A_LOG.Error("将http连接升级为websocket连接失败", zap.Any("err", err))
  88. return
  89. }
  90. client.SetQuoteWebSocket(ws)
  91. return
  92. }
  93. // QuoteSubscribe 设置客户订阅商品信息
  94. func QuoteSubscribe(c *gin.Context, req request.QuoteSubscribeReq) (err error) {
  95. // 获取请求账号信息
  96. s, exists := c.Get("claims")
  97. if !exists {
  98. err = errors.New("获取请求账号信息异常")
  99. global.M2A_LOG.Error(err.Error())
  100. return
  101. }
  102. claims := s.(*commonRequest.CustomClaims)
  103. // 获取登录账户信息
  104. client, exists := client.Clients[claims.SessionID]
  105. if !exists {
  106. err = errors.New("获取登录账户信息异常")
  107. global.M2A_LOG.Error(err.Error())
  108. return
  109. }
  110. // 设置客户订阅商品信息
  111. client.SetQuoteSubs(req)
  112. return
  113. }