package tracker import ( "net/http" "github.com/gorilla/websocket" "github.com/labstack/echo/v4" "github.com/rombintu/godpn/internal/models" ) func (s *Server) registerHandler(c echo.Context) error { var peer models.PeerManifest if err := c.Bind(peer); err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid request"}) } if peer.PubKey == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "pubkey is required"}) } ip := c.RealIP() if peer.IP != "" { ip = peer.IP } s.mu.Lock() s.tracker.peers[ip] = peer.PubKey s.mu.Unlock() return c.JSON(http.StatusOK, map[string]string{ "status": "registered", "ip": ip, }) } // Обработчик списка peers (HTTP) func (s *Server) listPeers(c echo.Context) error { s.mu.RLock() defer s.mu.RUnlock() return c.JSON(http.StatusOK, s.tracker.peers) } // WebSocket handler для реального времени func (s *Server) websocketHandler(c echo.Context) error { upgrader := websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil) if err != nil { return err } defer ws.Close() // Отправляем текущий список peers при подключении s.mu.RLock() if err := ws.WriteJSON(s.tracker.peers); err != nil { s.mu.RUnlock() return err } s.mu.RUnlock() // Ожидаем новые сообщения (можно добавить heartbeat) for { _, _, err := ws.ReadMessage() if err != nil { break } } return nil }