package coordinator 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 node models.PeerNode if err := c.Bind(node); err != nil { return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid request"}) } if node.PublicKey == "" { return c.JSON(http.StatusBadRequest, map[string]string{"error": "public key is required"}) } ip := c.RealIP() if node.Endpoint != "" { ip = node.Endpoint } s.mu.Lock() s.coordinator.peers[ip] = node s.mu.Unlock() return c.JSON(http.StatusOK, map[string]models.PeerNode{ "registered": node, }) } // Обработчик списка peers (HTTP) func (s *Server) listPeers(c echo.Context) error { s.mu.RLock() defer s.mu.RUnlock() return c.JSON(http.StatusOK, s.coordinator.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.coordinator.peers); err != nil { s.mu.RUnlock() return err } s.mu.RUnlock() // Ожидаем новые сообщения (можно добавить heartbeat) for { _, _, err := ws.ReadMessage() if err != nil { break } } return nil }