From 1080328afab761362f06c5fd1ebb55e1c0979c04 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Tue, 10 Nov 2020 15:22:30 +0100 Subject: [PATCH 1/2] FIX: cowebsite transitions are now queued to prevent conflicts --- front/src/WebRtc/CoWebsiteManager.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/front/src/WebRtc/CoWebsiteManager.ts b/front/src/WebRtc/CoWebsiteManager.ts index 46d03702..70d171a2 100644 --- a/front/src/WebRtc/CoWebsiteManager.ts +++ b/front/src/WebRtc/CoWebsiteManager.ts @@ -16,6 +16,11 @@ class CoWebsiteManager { private opened: iframeStates = iframeStates.closed; private observers = new Array(); + /** + * Quickly going in and out of an iframe trigger can create conflicts between the iframe states. + * So we use this promise to queue up every cowebsite state transition + */ + private currentOperationPromise: Promise = Promise.resolve(); private close(): HTMLDivElement { const cowebsiteDiv = HtmlUtils.getElementByIdOrFail(cowebsiteDivId); @@ -52,7 +57,7 @@ class CoWebsiteManager { const onTimeoutPromise = new Promise((resolve) => { setTimeout(() => resolve(), 2000); }); - Promise.race([onloadPromise, onTimeoutPromise]).then(() => { + this.currentOperationPromise = this.currentOperationPromise.then(() =>Promise.race([onloadPromise, onTimeoutPromise])).then(() => { this.open(); setTimeout(() => { this.fire(); @@ -65,7 +70,7 @@ class CoWebsiteManager { */ public insertCoWebsite(callback: (cowebsite: HTMLDivElement) => Promise): void { const cowebsiteDiv = this.load(); - callback(cowebsiteDiv).then(() => { + this.currentOperationPromise = this.currentOperationPromise.then(() => callback(cowebsiteDiv)).then(() => { this.open(); setTimeout(() => { this.fire(); @@ -74,14 +79,16 @@ class CoWebsiteManager { } public closeCoWebsite(): Promise { - return new Promise((resolve, reject) => { + this.currentOperationPromise = this.currentOperationPromise.then(() => new Promise((resolve, reject) => { + if(this.opened === iframeStates.closed) resolve(); //this method may be called twice, in case of iframe error for example const cowebsiteDiv = this.close(); this.fire(); setTimeout(() => { resolve(); setTimeout(() => cowebsiteDiv.innerHTML = '', 500) }, animationTime) - }); + })); + return this.currentOperationPromise; } public getGameSize(): {width: number, height: number} { From 5a1147866cffbaba1c92e389cd6fe87ed30222c9 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Tue, 10 Nov 2020 15:24:02 +0100 Subject: [PATCH 2/2] FIX: in dev mode, sockets won't be closed to prevent conflicts with live-reloading --- back/src/Enum/EnvironmentVariable.ts | 2 ++ back/src/Services/IoSocketHelpers.ts | 2 ++ docker-compose.yaml | 1 + 3 files changed, 5 insertions(+) diff --git a/back/src/Enum/EnvironmentVariable.ts b/back/src/Enum/EnvironmentVariable.ts index 55fd1bb7..8be8d54d 100644 --- a/back/src/Enum/EnvironmentVariable.ts +++ b/back/src/Enum/EnvironmentVariable.ts @@ -10,6 +10,7 @@ const CPU_OVERHEAT_THRESHOLD = Number(process.env.CPU_OVERHEAT_THRESHOLD) || 80; const JITSI_URL : string|undefined = (process.env.JITSI_URL === '') ? undefined : process.env.JITSI_URL; const JITSI_ISS = process.env.JITSI_ISS || ''; const SECRET_JITSI_KEY = process.env.SECRET_JITSI_KEY || ''; +const DEV_MODE = process.env.DEV_MODE || false; export { SECRET_KEY, @@ -21,6 +22,7 @@ export { GROUP_RADIUS, ALLOW_ARTILLERY, CPU_OVERHEAT_THRESHOLD, + DEV_MODE, JITSI_URL, JITSI_ISS, SECRET_JITSI_KEY diff --git a/back/src/Services/IoSocketHelpers.ts b/back/src/Services/IoSocketHelpers.ts index acaa0bb9..1dbfa0bd 100644 --- a/back/src/Services/IoSocketHelpers.ts +++ b/back/src/Services/IoSocketHelpers.ts @@ -1,5 +1,6 @@ import {ExSocketInterface} from "_Model/Websocket/ExSocketInterface"; import {BatchMessage, ErrorMessage, ServerToClientMessage, SubMessage} from "../Messages/generated/messages_pb"; +import {DEV_MODE} from "../Enum/EnvironmentVariable"; export function emitInBatch(socket: ExSocketInterface, payload: SubMessage): void { socket.batchedMessages.addPayload(payload); @@ -52,6 +53,7 @@ export function emitError(Client: ExSocketInterface, message: string): void { export const pongMaxInterval = 30000; // the maximum duration (in ms) between pongs before we shutdown the connexion. export function refresLogoutTimerOnPong(ws: ExSocketInterface): void { + if (DEV_MODE) return; //this feature is disabled in dev mode as it clashes with live reload. if(ws.pongTimeout) clearTimeout(ws.pongTimeout); ws.pongTimeout = setTimeout(() => { ws.close(); diff --git a/docker-compose.yaml b/docker-compose.yaml index 482dfbcb..5deccb4d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -78,6 +78,7 @@ services: ADMIN_API_TOKEN: "$ADMIN_API_TOKEN" JITSI_URL: $JITSI_URL JITSI_ISS: $JITSI_ISS + DEV_MODE: "1" volumes: - ./back:/usr/src/app labels: