diff --git a/cmd/client/connection_wasm.go b/cmd/client/connection_wasm.go index 8df3cd4..6c52188 100644 --- a/cmd/client/connection_wasm.go +++ b/cmd/client/connection_wasm.go @@ -27,6 +27,8 @@ type wsConn struct { // disconnectFromServer trennt die bestehende WebSocket-Verbindung sauber func (g *Game) disconnectFromServer() { + // Generation erhöhen → alle noch laufenden Handler der alten Verbindung werden ignoriert + g.connGeneration++ if g.wsConn != nil { g.wsConn.ws.Call("close") g.wsConn = nil @@ -53,8 +55,16 @@ func (g *Game) connectToServer() { connected: false, } + // Generation zum Zeitpunkt der Verbindung festhalten. + // Wenn disconnectFromServer() aufgerufen wird, erhöht sich g.connGeneration + // und alle Handler dieser alten Verbindung geben sofort nil zurück. + myGen := g.connGeneration + // OnOpen Handler ws.Call("addEventListener", "open", js.FuncOf(func(this js.Value, args []js.Value) interface{} { + if g.connGeneration != myGen { + return nil // veraltete Verbindung + } log.Println("✅ WebSocket verbunden!") conn.connected = true g.connected = true @@ -63,6 +73,9 @@ func (g *Game) connectToServer() { // OnMessage Handler ws.Call("addEventListener", "message", js.FuncOf(func(this js.Value, args []js.Value) interface{} { + if g.connGeneration != myGen { + return nil // veraltete Verbindung – Nachrichten ignorieren + } if len(args) == 0 { return nil } @@ -149,6 +162,9 @@ func (g *Game) connectToServer() { // OnError Handler ws.Call("addEventListener", "error", js.FuncOf(func(this js.Value, args []js.Value) interface{} { + if g.connGeneration != myGen { + return nil // veraltete Verbindung + } log.Println("❌ WebSocket Fehler!") conn.connected = false g.connected = false @@ -157,6 +173,9 @@ func (g *Game) connectToServer() { // OnClose Handler ws.Call("addEventListener", "close", js.FuncOf(func(this js.Value, args []js.Value) interface{} { + if g.connGeneration != myGen { + return nil // veraltete Verbindung – kein g.connected überschreiben + } log.Println("🔌 WebSocket geschlossen") conn.connected = false g.connected = false diff --git a/cmd/client/main.go b/cmd/client/main.go index 0c9791d..527b5a0 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -57,10 +57,12 @@ type InputState struct { type Game struct { appState int conn *nats.EncodedConn - wsConn *wsConn // WebSocket für WASM - gameState game.GameState - stateMutex sync.Mutex - connected bool + wsConn *wsConn // WebSocket für WASM + connGeneration int // Erhöht bei jedem Disconnect; macht alte WS-Handler ungültig + isConnecting bool // Guard gegen mehrfaches connectAndStart() + gameState game.GameState + stateMutex sync.Mutex + connected bool world *game.World assetsImages map[string]*ebiten.Image @@ -904,6 +906,14 @@ func (g *Game) resetForNewGame() { } func (g *Game) connectAndStart() { + // Guard: verhindert mehrfaches gleichzeitiges Verbinden + if g.isConnecting { + log.Println("⚠️ connectAndStart bereits aktiv, ignoriere doppelten Aufruf") + return + } + g.isConnecting = true + defer func() { g.isConnecting = false }() + g.resetForNewGame() // Verbindung über plattformspezifische Implementierung diff --git a/cmd/client/web/index.html b/cmd/client/web/index.html index 30b2236..2b0704f 100644 --- a/cmd/client/web/index.html +++ b/cmd/client/web/index.html @@ -425,7 +425,7 @@ const _loadingQuoteInterval = setInterval(function() { } else { clearInterval(_loadingQuoteInterval); } -}, 4000); +}, 10000); function showSprueche() { document.querySelectorAll('.overlay-screen').forEach(el => el.classList.add('hidden'));