chatcontroller.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package controller
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/gin-gonic/gin"
  6. "github.com/gorilla/websocket"
  7. "net/http"
  8. "strconv"
  9. "time"
  10. "trading-go/model"
  11. "trading-go/response"
  12. )
  13. var UP = websocket.Upgrader{
  14. ReadBufferSize: 1024,
  15. WriteBufferSize: 1024,
  16. }
  17. type client struct {
  18. conn *websocket.Conn
  19. pip chan *model.Message
  20. }
  21. var Conns map[uint]*client
  22. func init() {
  23. Conns = make(map[uint]*client)
  24. }
  25. // 发送消息
  26. func send(conn *websocket.Conn, uid uint) {
  27. pip := Conns[uid].pip
  28. defer func() {
  29. delete(Conns, uid)
  30. }()
  31. for {
  32. data := <-pip
  33. data.Save()
  34. msg, err := json.Marshal(data)
  35. if err != nil {
  36. fmt.Println("link closed")
  37. break
  38. }
  39. err = conn.WriteMessage(data.MsgType, msg)
  40. if err != nil {
  41. fmt.Println(err.Error())
  42. break
  43. }
  44. }
  45. }
  46. // 接收消息
  47. func reception(conn *websocket.Conn, uid uint) {
  48. defer func() {
  49. delete(Conns, uid)
  50. }()
  51. for {
  52. var msg model.Message
  53. err := conn.ReadJSON(&msg)
  54. if err != nil {
  55. fmt.Println(err.Error())
  56. break
  57. }
  58. msg.Save()
  59. if v, ok := Conns[msg.To]; ok {
  60. v.pip <- &msg
  61. } else {
  62. }
  63. }
  64. }
  65. func broadcast(data model.Message) {
  66. for _, conn := range Conns {
  67. msg, err := json.Marshal(data)
  68. if err != nil {
  69. fmt.Println(err.Error())
  70. break
  71. }
  72. err = conn.conn.WriteMessage(data.MsgType, msg)
  73. if err != nil {
  74. fmt.Println(err.Error())
  75. break
  76. }
  77. }
  78. }
  79. func heartBeat(uid uint) {
  80. defer func() {
  81. delete(Conns, uid)
  82. }()
  83. for {
  84. msg := model.Message{
  85. MsgType: 4,
  86. From: 0,
  87. To: uid,
  88. Time: uint(time.Now().Unix()),
  89. Content: "alive",
  90. }
  91. if v, ok := Conns[msg.To]; ok {
  92. v.pip <- &msg
  93. time.Sleep(time.Second)
  94. } else {
  95. }
  96. }
  97. }
  98. func Chat(w http.ResponseWriter, rq *http.Request, uid uint) {
  99. // 升级为websocket
  100. conn, err := UP.Upgrade(w, rq, nil)
  101. if err != nil {
  102. response.Fail(w, err.Error(), http.StatusUpgradeRequired)
  103. return
  104. }
  105. pip := make(chan *model.Message, 1024)
  106. client := client{
  107. conn: conn,
  108. pip: pip,
  109. }
  110. Conns[uid] = &client
  111. go send(conn, uid)
  112. go reception(conn, uid)
  113. go heartBeat(uid)
  114. response.Success(w, "success", nil)
  115. }
  116. // LinkToServer
  117. // @Tags 聊天模块
  118. // @Summary 与服务端进行websocket连接,请使用postman测试
  119. // @Success 200 {object} response.Response
  120. // @Router /chat [get]
  121. func LinkToServer(c *gin.Context) {
  122. uid, err := strconv.Atoi(c.Query("uid"))
  123. if err != nil {
  124. response.Fail(c.Writer, "failed", 500)
  125. return
  126. }
  127. Chat(c.Writer, c.Request, uint(uid))
  128. }
  129. // GetMsgFromPaged
  130. // @Tags 聊天模块
  131. // @Summary 获取未过期且来源为特定用户的聊天记录
  132. // @Success 200 {object} response.Response
  133. // @Param uid query string true "用户id"
  134. // @Router /chat/from [get]
  135. func GetMsgFromPaged(c *gin.Context) {
  136. id := c.Query("uid")
  137. uid, err := strconv.ParseUint(id, 10, 64)
  138. if err != nil {
  139. msg := err.Error()
  140. response.Fail(c.Writer, msg, 500)
  141. return
  142. }
  143. msgs, err := model.Message{}.GetFrom(uint(uid))
  144. if err != nil {
  145. response.Fail(c.Writer, err.Error(), 500)
  146. return
  147. }
  148. response.Success(c.Writer, "success", msgs)
  149. }
  150. // GetMsgToPaged
  151. // @Tags 聊天模块
  152. // @Summary 获取未过期且目标为特定用户的聊天记录
  153. // @Success 200 {object} response.Response
  154. // @Param uid query string true "用户id"
  155. // @Router /chat/to [get]
  156. func GetMsgToPaged(c *gin.Context) {
  157. id := c.Query("uid")
  158. uid, err := strconv.ParseUint(id, 10, 64)
  159. if err != nil {
  160. msg := err.Error()
  161. response.Fail(c.Writer, msg, 500)
  162. return
  163. }
  164. msgs, err := model.Message{}.GetTo(uint(uid))
  165. if err != nil {
  166. response.Fail(c.Writer, err.Error(), 500)
  167. return
  168. }
  169. response.Success(c.Writer, "success", msgs)
  170. }