websocket.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // Package handlers
  2. package handlers
  3. import (
  4. "log"
  5. "net/http"
  6. "sync"
  7. "github.com/gorilla/websocket"
  8. )
  9. var upgrader = websocket.Upgrader{
  10. CheckOrigin: func(r *http.Request) bool { return true },
  11. }
  12. type VisitorDot struct {
  13. UserID string `json:"user_id,omitempty"`
  14. Lat float64 `json:"lat"`
  15. Lng float64 `json:"lng"`
  16. }
  17. type WSHub struct {
  18. mu sync.RWMutex
  19. clients map[*websocket.Conn]VisitorDot
  20. }
  21. func NewWSHub() *WSHub {
  22. return &WSHub{clients: make(map[*websocket.Conn]VisitorDot)}
  23. }
  24. func (h *WSHub) HandleWS(w http.ResponseWriter, r *http.Request) {
  25. conn, err := upgrader.Upgrade(w, r, nil)
  26. if err != nil {
  27. log.Printf("ws upgrade: %v", err)
  28. return
  29. }
  30. dot := VisitorDot{}
  31. h.mu.Lock()
  32. h.clients[conn] = dot
  33. h.mu.Unlock()
  34. defer func() {
  35. h.mu.Lock()
  36. delete(h.clients, conn)
  37. h.mu.Unlock()
  38. conn.Close()
  39. }()
  40. for {
  41. var msg VisitorDot
  42. if err := conn.ReadJSON(&msg); err != nil {
  43. break
  44. }
  45. h.mu.Lock()
  46. h.clients[conn] = msg
  47. visitors := make([]VisitorDot, 0, len(h.clients))
  48. for _, v := range h.clients {
  49. visitors = append(visitors, v)
  50. }
  51. for c := range h.clients {
  52. if err := c.WriteJSON(map[string]interface{}{"visitors": visitors}); err != nil {
  53. c.Close()
  54. delete(h.clients, c)
  55. }
  56. }
  57. h.mu.Unlock()
  58. }
  59. }