client.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package server
  2. import (
  3. "encoding/json"
  4. "time"
  5. "github.com/gin-gonic/gin"
  6. "github.com/google/uuid"
  7. "github.com/gorilla/websocket"
  8. "sikey.com/websocket/models"
  9. "sikey.com/websocket/repositories"
  10. "sikey.com/websocket/utils/zlog"
  11. )
  12. type Client struct {
  13. ctx *gin.Context
  14. UserId string
  15. hub *Hub
  16. UnderlyingConn *websocket.Conn
  17. isRemotely bool // isRemotely 是否是远程连接
  18. isSimpleMsg bool // isSimpleMsg 是否是简单消息
  19. localization string // localization 国际码
  20. // Send message channel 发送消息
  21. // 当用户在线时会通过 Send channel 发送在线消息 但如果用户不在线,
  22. Send chan *Message
  23. readWait time.Duration // readWait 读超时
  24. writeWait time.Duration // writeWait 写超时
  25. pingWait time.Duration // pingWait 心跳超时
  26. repos *repositories.Repositories
  27. }
  28. func (c *Client) reader() {
  29. defer func() {
  30. c.hub.Disconnect <- c
  31. c.UnderlyingConn.Close()
  32. }()
  33. c.UnderlyingConn.SetReadDeadline(time.Now().Add(c.readWait))
  34. for {
  35. _, bytes, err := c.UnderlyingConn.ReadMessage()
  36. if err != nil {
  37. if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
  38. zlog.Errorf("error: %v", err)
  39. }
  40. break
  41. }
  42. message := deserializeMessage(bytes)
  43. switch message.Type {
  44. case MessageTypeUpChating, MessageTypeDownChating:
  45. // Chat dialogue messages
  46. chatingContent := message.Content.(ChatingContent)
  47. // Save message to database
  48. payload, _ := json.Marshal(chatingContent.Payload)
  49. messageId := uuid.NewString()
  50. err = c.repos.SessionRepository.CreateMessage(c.ctx, &models.SessionMessage{
  51. ID: messageId,
  52. SessionId: chatingContent.Receiver,
  53. Receiver: chatingContent.Receiver,
  54. Sender: c.UserId,
  55. Type: uint8(message.Type),
  56. ContentType: uint8(chatingContent.PayloadType),
  57. Content: string(payload),
  58. IsRead: false,
  59. })
  60. if err != nil {
  61. c.writeError(message.RequestId, err)
  62. continue
  63. }
  64. members, err := c.repos.SessionRepository.GetSessionMembersRemoveOneself(
  65. c.ctx, chatingContent.Receiver, c.UserId)
  66. if err != nil {
  67. c.writeError(message.RequestId, err)
  68. continue
  69. }
  70. chatingContent.MessageId = messageId
  71. for _, member := range members {
  72. var messaging = *message
  73. messaging.receiver = member.AccountId
  74. messaging.Content = chatingContent
  75. c.hub.Message <- &messaging
  76. zlog.Info("Send message to ", member.AccountId)
  77. }
  78. // Reply message id
  79. message.Content = &ContentReply{MessageId: messageId}
  80. }
  81. // Reply message
  82. if message.IsNeedReply() {
  83. c.Send <- newReplyMessage(message)
  84. // Reset read deadline, prevent Reader from shutting down
  85. c.UnderlyingConn.SetReadDeadline(time.Now().Add(c.pingWait))
  86. }
  87. }
  88. }
  89. func (c *Client) writer() {
  90. ticker := time.NewTicker(c.pingWait)
  91. defer func() {
  92. ticker.Stop()
  93. c.UnderlyingConn.Close()
  94. }()
  95. for {
  96. select {
  97. case message, ok := <-c.Send:
  98. c.UnderlyingConn.SetWriteDeadline(time.Now().Add(c.writeWait))
  99. if !ok {
  100. // The hub closed the channel.
  101. c.UnderlyingConn.WriteMessage(websocket.CloseMessage, []byte{})
  102. return
  103. }
  104. var err error
  105. err = c.UnderlyingConn.WriteMessage(websocket.TextMessage, serializationMessage(message))
  106. if err != nil {
  107. return
  108. }
  109. case <-ticker.C:
  110. // 到时间发送 ping 信号
  111. c.UnderlyingConn.SetWriteDeadline(time.Now().Add(c.writeWait))
  112. if err := c.UnderlyingConn.WriteMessage(websocket.PingMessage, nil); err != nil {
  113. return
  114. }
  115. }
  116. }
  117. }
  118. func (c *Client) writeError(requestId string, err error) {
  119. c.Send <- &Message{
  120. RequestId: requestId,
  121. Type: MessageTypeError,
  122. Content: ContentError{Err: err.Error()},
  123. }
  124. }