// /futriis/internal/server/server.go // Пакет server реализует серверную часть для клиент-серверной архитектуры package server import ( "bufio" "encoding/json" "net" "sync" "futriis/internal/engine" "futriis/pkg/utils" ) // Server представляет сервер СУБД type Server struct { address string engine *engine.Engine listener net.Listener clients map[net.Conn]bool mu sync.RWMutex stopChan chan struct{} } // NewServer создаёт новый сервер func NewServer(address string, engine *engine.Engine) *Server { return &Server{ address: address, engine: engine, clients: make(map[net.Conn]bool), stopChan: make(chan struct{}), } } // Start запускает сервер func (s *Server) Start() error { listener, err := net.Listen("tcp", s.address) if err != nil { return err } s.listener = listener utils.PrintSuccess("Сервер запущен на %s", s.address) go s.acceptLoop() return nil } // acceptLoop принимает входящие соединения func (s *Server) acceptLoop() { for { select { case <-s.stopChan: return default: conn, err := s.listener.Accept() if err != nil { continue } s.mu.Lock() s.clients[conn] = true s.mu.Unlock() go s.handleClient(conn) } } } // handleClient обрабатывает клиентское соединение func (s *Server) handleClient(conn net.Conn) { defer func() { s.mu.Lock() delete(s.clients, conn) s.mu.Unlock() conn.Close() }() scanner := bufio.NewScanner(conn) for scanner.Scan() { line := scanner.Text() // Парсим JSON запрос var req map[string]interface{} if err := json.Unmarshal([]byte(line), &req); err != nil { // Если не JSON, обрабатываем как простую команду result, err := s.engine.Execute(line) s.sendResponse(conn, result, err) } else { // Обрабатываем JSON запрос cmd, _ := req["command"].(string) result, err := s.engine.Execute(cmd) s.sendResponse(conn, result, err) } } } // sendResponse отправляет ответ клиенту func (s *Server) sendResponse(conn net.Conn, result string, err error) { response := make(map[string]interface{}) if err != nil { response["error"] = err.Error() } else { response["result"] = result } data, _ := json.Marshal(response) conn.Write(append(data, '\n')) } // Stop останавливает сервер func (s *Server) Stop() { close(s.stopChan) if s.listener != nil { s.listener.Close() } s.mu.Lock() for conn := range s.clients { conn.Close() } s.mu.Unlock() }