ws.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package initialize
  2. import (
  3. "encoding/json"
  4. "github.com/gin-gonic/gin"
  5. "github.com/gorilla/websocket"
  6. "log"
  7. "net/http"
  8. )
  9. // ClientManager is a websocket manager
  10. type ClientManager struct {
  11. Clients map[string]*Client
  12. Broadcast chan []byte
  13. Register chan *Client
  14. Unregister chan *Client
  15. }
  16. // Client is a websocket client
  17. type Client struct {
  18. ID string
  19. Socket *websocket.Conn
  20. Send chan []byte
  21. }
  22. // Message is return msg
  23. type Message struct {
  24. Sender string `json:"sender,omitempty"`
  25. Recipient string `json:"recipient,omitempty"`
  26. Content string `json:"content,omitempty"`
  27. }
  28. // Manager define a ws server manager
  29. var Manager = ClientManager{
  30. Broadcast: make(chan []byte),
  31. Register: make(chan *Client),
  32. Unregister: make(chan *Client),
  33. Clients: make(map[string]*Client),
  34. }
  35. // Start is 项目运行前, 协程开启start -> go Manager.Start()
  36. func (manager *ClientManager) Start() {
  37. for {
  38. log.Println("<---管道通信--->")
  39. select {
  40. case conn := <-Manager.Register:
  41. log.Printf("新用户加入:%v", conn.ID)
  42. Manager.Clients[conn.ID] = conn
  43. jsonMessage, _ := json.Marshal(&Message{Content: "Successful connection to socket service"})
  44. conn.Send <- jsonMessage
  45. case conn := <-Manager.Unregister:
  46. log.Printf("用户离开:%v", conn.ID)
  47. if _, ok := Manager.Clients[conn.ID]; ok {
  48. jsonMessage, _ := json.Marshal(&Message{Content: "A socket has disconnected"})
  49. conn.Send <- jsonMessage
  50. close(conn.Send)
  51. delete(Manager.Clients, conn.ID)
  52. }
  53. case message := <-Manager.Broadcast:
  54. MessageStruct := Message{}
  55. err := json.Unmarshal(message, &MessageStruct)
  56. if err != nil {
  57. panic(err)
  58. return
  59. }
  60. for id, conn := range Manager.Clients {
  61. if id != creatId(MessageStruct.Recipient, MessageStruct.Sender) {
  62. continue
  63. }
  64. select {
  65. case conn.Send <- message:
  66. default:
  67. close(conn.Send)
  68. delete(Manager.Clients, conn.ID)
  69. }
  70. }
  71. }
  72. }
  73. }
  74. func creatId(uid, touid string) string {
  75. return uid + "_" + touid
  76. }
  77. func (c *Client) Read() {
  78. //defer func() {
  79. // Manager.Unregister <- c
  80. // c.Socket.Close()
  81. //}()
  82. for {
  83. c.Socket.PongHandler()
  84. _, message, err := c.Socket.ReadMessage()
  85. if err != nil {
  86. Manager.Unregister <- c
  87. c.Socket.Close()
  88. break
  89. }
  90. log.Printf("读取到客户端的信息:%s", string(message))
  91. Manager.Broadcast <- message
  92. }
  93. }
  94. func (c *Client) Write() {
  95. //defer func() {
  96. // c.Socket.Close()
  97. //}()
  98. for {
  99. select {
  100. case message, ok := <-c.Send:
  101. if !ok {
  102. c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
  103. return
  104. }
  105. log.Printf("发送到到客户端的信息:%s", string(message))
  106. c.Socket.WriteMessage(websocket.TextMessage, message)
  107. }
  108. }
  109. }
  110. // WsHandler TestHandler socket 连接 中间件 作用:升级协议,用户验证,自定义信息等
  111. func WsHandler(c *gin.Context) {
  112. uid := c.Query("uid")
  113. touid := c.Query("to_uid")
  114. conn, err := (&websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}).Upgrade(c.Writer, c.Request, nil)
  115. if err != nil {
  116. http.NotFound(c.Writer, c.Request)
  117. return
  118. }
  119. //可以添加用户信息验证
  120. client := &Client{
  121. ID: creatId(uid, touid),
  122. Socket: conn,
  123. Send: make(chan []byte),
  124. }
  125. Manager.Register <- client
  126. go client.Read()
  127. go client.Write()
  128. }