diff --git a/web/server.go b/web/server.go index 604305e..dfe6ed8 100644 --- a/web/server.go +++ b/web/server.go @@ -82,6 +82,19 @@ func (s *Server) routes() { // Middleware s.router.Use(middleware.Logger) s.router.Use(middleware.Recoverer) + // Add timeout middleware with a longer duration for SSE connections + s.router.Use(middleware.Timeout(120 * time.Second)) + // Add middleware to set appropriate headers for SSE + s.router.Use(func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.Contains(r.URL.Path, "/api/events") || strings.Contains(r.URL.Path, "/api/admin/events") { + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("Access-Control-Allow-Origin", "*") + } + next.ServeHTTP(w, r) + }) + }) // Create a file server for static files staticFS, err := fs.Sub(content, "static") @@ -170,17 +183,15 @@ func (s *Server) Start() error { s.server = &http.Server{ Addr: addr, Handler: s.router, + // Add these settings to handle multiple concurrent connections + ReadTimeout: 30 * time.Second, + WriteTimeout: 60 * time.Second, // Longer timeout for SSE connections + MaxHeaderBytes: 1 << 20, // 1 MB + IdleTimeout: 120 * time.Second, } - // Start server in a goroutine - go func() { - s.logger.Info("Web server starting", "port", s.port) - if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { - s.logger.Error("HTTP server error", "error", err) - } - }() - - return nil + s.logger.Info("Starting web server", "port", s.port) + return s.server.ListenAndServe() } // Stop gracefully shuts down the server @@ -222,7 +233,7 @@ func (s *Server) forwardEvents() { } } -// broadcastEvent sends an event to all connected clients +// broadcastRaceEvent sends a race event to all connected clients func (s *Server) broadcastRaceEvent(event derby.Event) { var heatResult models.HeatResult switch event.Type {