Private
Public Access
1
0

Add Docker, Kubernetes configurations, and CI workflows for deployment. Integrate Gin server for API, WebSocket support, and static file hosting. Refactor WebSocket gateway to use Gin router.
Dynamic Branch Deploy / build-and-deploy (push) Has been cancelled

This commit is contained in:
Sebastian Unterschütz
2026-01-04 15:14:55 +01:00
parent 2fb19d314f
commit 16f683a360
13 changed files with 872 additions and 13 deletions
+88
View File
@@ -0,0 +1,88 @@
package main
import (
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/nats-io/nats.go"
)
// SetupGinServer erstellt und konfiguriert den Gin-Server
func SetupGinServer(ec *nats.EncodedConn, port string) *gin.Engine {
// Production mode für bessere Performance
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
// Logging Middleware (bereits in gin.Default())
// Custom Logger für bessere Übersicht
r.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
return "🌐 " + param.TimeStamp.Format("2006-01-02 15:04:05") +
" | " + param.Method +
" | " + string(rune(param.StatusCode)) +
" | " + param.Latency.String() +
" | " + param.ClientIP +
" | " + param.Path + "\n"
}))
// Recovery Middleware
r.Use(gin.Recovery())
// Health Check Endpoint
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{
"status": "ok",
"service": "EscapeFromTeacher",
"version": "1.0.0",
})
})
// Metrics Endpoint (optional für Kubernetes)
r.GET("/metrics", func(c *gin.Context) {
mu.RLock()
roomCount := len(rooms)
playerCount := len(playerSessions)
mu.RUnlock()
c.JSON(200, gin.H{
"rooms": roomCount,
"players": playerCount,
})
})
// WebSocket Endpoint
r.GET("/ws", func(c *gin.Context) {
handleWebSocketGin(c.Writer, c.Request, ec)
})
// Static Files - Serve Web Client
r.Static("/assets", "./cmd/client/web/assets")
r.StaticFile("/", "./cmd/client/web/index.html")
r.StaticFile("/index.html", "./cmd/client/web/index.html")
r.StaticFile("/game.js", "./cmd/client/web/game.js")
r.StaticFile("/style.css", "./cmd/client/web/style.css")
r.StaticFile("/wasm_exec.js", "./cmd/client/web/wasm_exec.js")
r.StaticFile("/main.wasm", "./cmd/client/web/main.wasm")
r.StaticFile("/background.jpg", "./cmd/client/web/background.jpg")
// 404 Handler
r.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{
"error": "Route not found",
})
})
log.Printf("🚀 Gin-Server konfiguriert auf Port %s", port)
log.Printf("📁 Statische Dateien: ./cmd/client/web/")
log.Printf("🌐 WebSocket Endpoint: /ws")
log.Printf("❤️ Health Check: /health")
return r
}
// handleWebSocketGin verwaltet WebSocket-Verbindungen über Gin
func handleWebSocketGin(w http.ResponseWriter, r *http.Request, ec *nats.EncodedConn) {
// Verwende die handleWebSocket Funktion aus websocket_gateway.go
handleWebSocket(w, r, ec)
}
+5 -5
View File
@@ -172,11 +172,11 @@ func main() {
log.Println("✅ Server bereit. Warte auf Spieler...")
// 9. WEBSOCKET-GATEWAY STARTEN (für Browser-Clients)
go StartWebSocketGateway("8080", ec)
// Block forever
select {}
// 9. GIN-SERVER STARTEN (statische Dateien + WebSocket)
router := SetupGinServer(ec, "8080")
if err := router.Run(":8080"); err != nil {
log.Fatal("❌ Gin-Server Fehler:", err)
}
}
func loadServerAssets(w *game.World) {