ws_client.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package handlers
  2. import (
  3. "encoding/json"
  4. "time"
  5. "github.com/gorilla/websocket"
  6. )
  7. const (
  8. writeWait = 10 * time.Second
  9. pongWait = 60 * time.Second
  10. pingPeriod = (pongWait * 9) / 10
  11. maxMessageSize = 4096
  12. )
  13. type wsMessage struct {
  14. Type string `json:"type"`
  15. Data json.RawMessage `json:"data"`
  16. }
  17. type Client struct {
  18. hub *WSHub
  19. conn *websocket.Conn
  20. send chan []byte
  21. userID string
  22. lat float64
  23. lng float64
  24. }
  25. func (c *Client) readPump() {
  26. defer func() {
  27. c.hub.unregister <- c
  28. c.conn.Close()
  29. }()
  30. c.conn.SetReadLimit(maxMessageSize)
  31. c.conn.SetReadDeadline(time.Now().Add(pongWait))
  32. c.conn.SetPongHandler(func(string) error {
  33. c.conn.SetReadDeadline(time.Now().Add(pongWait))
  34. return nil
  35. })
  36. for {
  37. var msg wsMessage
  38. if err := c.conn.ReadJSON(&msg); err != nil {
  39. break
  40. }
  41. switch msg.Type {
  42. case "visitor_update":
  43. var dot VisitorDot
  44. if err := json.Unmarshal(msg.Data, &dot); err != nil {
  45. continue
  46. }
  47. c.userID = dot.UserID
  48. c.lat = dot.Lat
  49. c.lng = dot.Lng
  50. c.hub.broadcastVisitors()
  51. }
  52. }
  53. }
  54. func (c *Client) writePump() {
  55. ticker := time.NewTicker(pingPeriod)
  56. defer func() {
  57. ticker.Stop()
  58. c.conn.Close()
  59. }()
  60. for {
  61. select {
  62. case message, ok := <-c.send:
  63. c.conn.SetWriteDeadline(time.Now().Add(writeWait))
  64. if !ok {
  65. c.conn.WriteMessage(websocket.CloseMessage, []byte{})
  66. return
  67. }
  68. if err := c.conn.WriteMessage(websocket.TextMessage, message); err != nil {
  69. return
  70. }
  71. case <-ticker.C:
  72. c.conn.SetWriteDeadline(time.Now().Add(writeWait))
  73. if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil {
  74. return
  75. }
  76. }
  77. }
  78. }