diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c628c8a7..755fd735 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -37,14 +37,11 @@ export class AppComponent implements OnInit { //Whenever user become inactive (25sec) -> open prompt. this.userInactive.subscribe(() => { - //Never open prompt on drawing page. - if (this.gameStateService.getCurrentPage() === GAMESTATE.drawingBoard) { - this.setDialogTimeout(); - } - if (this.router.url === '/welcome') { this.router.navigate(['/']); - } else if (this.router.url !== '/' && !this.router.url.startsWith('/admin')) { + + //avoids opening idle timeout box on initial page, admin page and while drawing + } else if (this.router.url !== '/' && !this.router.url.startsWith('/admin') && this.gameStateService.getCurrentPage() !== GAMESTATE.drawingBoard) { this.openDialog(); } }); diff --git a/src/app/game/game-multiplayer/lobby/lobby.component.ts b/src/app/game/game-multiplayer/lobby/lobby.component.ts index 87900714..d717167d 100644 --- a/src/app/game/game-multiplayer/lobby/lobby.component.ts +++ b/src/app/game/game-multiplayer/lobby/lobby.component.ts @@ -57,9 +57,6 @@ export class LobbyComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - if (this.initializeComponent) { - this.initializeComponent(); - } const difficulty = 2; // Difficulty set to medium (1 for easy, 3 for hard) this.subscriptions.add(this.multiPlayerService.joinGame(difficulty).subscribe()); this.subscriptions.add( diff --git a/src/app/game/game-multiplayer/multiplayer.component.ts b/src/app/game/game-multiplayer/multiplayer.component.ts index f1dde523..a6536c69 100644 --- a/src/app/game/game-multiplayer/multiplayer.component.ts +++ b/src/app/game/game-multiplayer/multiplayer.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { trigger, style, animate, transition } from '@angular/animations'; import { Router } from '@angular/router'; - import { MultiplayerService } from '../services/multiplayer.service'; import { WebSocketService } from '../services/web-socket.service'; import { Subscription } from 'rxjs'; @@ -103,7 +102,7 @@ export class MultiplayerComponent implements OnInit, OnDestroy { ngOnDestroy(): void { this.webSocketService.disconnect(); - this.multiplayerService.resetStateInfo(); + this.multiplayerService.clearState(); this.subs.unsubscribe(); } } diff --git a/src/app/game/services/multiplayer.service.ts b/src/app/game/services/multiplayer.service.ts index 28c2be9a..7d033b53 100644 --- a/src/app/game/services/multiplayer.service.ts +++ b/src/app/game/services/multiplayer.service.ts @@ -57,10 +57,6 @@ export class MultiplayerService { private translationService: TranslationService ) {} - resetStateInfo() { - this.stateInfo = this.initialState; - } - joinGame(difficulty_id: number) { this.webSocketService.emit( SocketEndpoints.JOIN_GAME, @@ -215,7 +211,6 @@ export class MultiplayerService { clearState() { this.stateInfo = this.initialState; - this.webSocketService.disconnect(); } changestate(gameState: GAMESTATE) { diff --git a/src/app/game/services/web-socket.service.ts b/src/app/game/services/web-socket.service.ts index 278cfa6a..80006a3d 100644 --- a/src/app/game/services/web-socket.service.ts +++ b/src/app/game/services/web-socket.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable, BehaviorSubject } from 'rxjs'; import { io, Socket } from 'socket.io-client'; +import { Router } from '@angular/router'; import { environment } from '@/environments/environment'; import { SocketEndpoints } from '@/app/shared/models/websocketEndpoints'; import { PlayerDisconnectedData } from '@/app/shared/models/interfaces'; @@ -11,27 +12,57 @@ import { GameStateService } from '../services/game-state-service'; }) export class WebSocketService { socket: Socket | undefined; + private retryAttempts = 0; + private maxRetries = 5; + private retryDelay = 3000; playerDisconnectedData: PlayerDisconnectedData | undefined; private readonly _playerDisconnected = new BehaviorSubject(false); readonly playerDisconnected$ = this._playerDisconnected.asObservable(); + private isConnected = false; + private isRetrying = false; - constructor(private gameStateService: GameStateService) {} + + constructor(private gameStateService: GameStateService, private router: Router) {} startSockets() { - this.socket = io(environment.WS_ENDPOINT); + if (this.socket && this.socket.connected) { + console.warn('Socket already connected'); + return; + } + + if (this.isRetrying) { + console.warn('Currently retrying connection; will not start a new connection.'); + return; + } + + this.isRetrying = true; + this.socket = io(environment.TEKNISKBACKEND_ENDPOINT); + + this.socket.on('connect', () => { + this.isConnected = true; + }) this.socket.on('connect_failed', () => { console.error('connect_failed'); + this.handleConnectionError(); + }); this.socket.on('connect_error', (error) => { console.error(error); + this.handleConnectionError(); }); - this.socket.on('disconnect', (reason) => { + // Disable any type check for only this one because the spread parameter will take parameters of different types + // eslint-disable-next-line @typescript-eslint/no-explicit-any + this.socket.on('disconnect', (reason: any) => { console.warn('disconnected', reason); + this.isConnected = false; + if (reason !== "io client disconnect") { + this.handleConnectionError(); + } }); this.socket.on('error', (reason) => { console.error('error', reason); @@ -47,10 +78,19 @@ export class WebSocketService { } disconnect() { - if (this.socket && !this.socket.disconnected) { + if (this.socket && ! this.socket.disconnected) { console.warn('socket disconnecting and removing listener'); this.socket.removeAllListeners(); this.socket.disconnect(); + this.socket = undefined; + this.isConnected = false; + this.isRetrying = false; + console.log("Websocket closed properly") + this.retryAttempts = 0; + } else if (this.socket) { + this.socket.removeAllListeners(); + this.socket.disconnect(); + console.log("Websocket closed properly without ever being connected") } } @@ -75,4 +115,24 @@ export class WebSocketService { set playerDisconnected(val: boolean) { this._playerDisconnected.next(val); } + + handleConnectionError() { + this.retryAttempts++; + + if (this.retryAttempts <= this.maxRetries) { + console.warn(`Retrying connection... Attempt ${this.retryAttempts}/${this.maxRetries}`); + setTimeout(() => { + this.startSockets(); + }, this.retryDelay); + } else { + console.error('Max retry attempts reached. Redirecting to welcome page.'); + this.redirectToWelcomePage(); + } + } + + redirectToWelcomePage() { + this.disconnect(); + this.router.navigate(['/welcome']) + } } +