From 9b64a970b57d094988073199451b47c857201ee1 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Tue, 10 Nov 2020 18:26:46 +0100 Subject: [PATCH] FIX: remove the ping and pong overrides server side in favor of and idleTimeout and added a manual ping client side --- back/src/Controller/IoSocketController.ts | 10 +++---- back/src/Enum/EnvironmentVariable.ts | 3 +-- back/src/Model/Websocket/ExSocketInterface.ts | 2 -- back/src/Services/IoSocketHelpers.ts | 26 ------------------- docker-compose.yaml | 1 - front/src/Connexion/RoomConnection.ts | 7 ++++- messages/messages.proto | 4 +++ 7 files changed, 14 insertions(+), 39 deletions(-) diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index c71edd86..85549c03 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -20,9 +20,9 @@ import {parse} from "query-string"; import {jwtTokenManager} from "../Services/JWTTokenManager"; import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "../Services/AdminApi"; import {SocketManager, socketManager} from "../Services/SocketManager"; -import {emitInBatch, pongMaxInterval, refresLogoutTimerOnPong, resetPing} from "../Services/IoSocketHelpers"; +import {emitInBatch} from "../Services/IoSocketHelpers"; import {clientEventsEmitter} from "../Services/ClientEventsEmitter"; -import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable"; +import {ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER} from "../Enum/EnvironmentVariable"; export class IoSocketController { private nextUserId: number = 1; @@ -110,6 +110,7 @@ export class IoSocketController { this.app.ws('/room', { /* Options */ //compression: uWS.SHARED_COMPRESSOR, + idleTimeout: SOCKET_IDLE_TIMER, maxPayloadLength: 16 * 1024 * 1024, maxBackpressure: 65536, // Maximum 64kB of data in the buffer. //idleTimeout: 10, @@ -239,8 +240,6 @@ export class IoSocketController { // Let's join the room const client = this.initClient(ws); //todo: into the upgrade instead? socketManager.handleJoinRoom(client); - resetPing(client); - refresLogoutTimerOnPong(ws as ExSocketInterface); //get data information and show messages if (ADMIN_API_URL) { @@ -293,9 +292,6 @@ export class IoSocketController { drain: (ws) => { console.log('WebSocket backpressure: ' + ws.getBufferedAmount()); }, - pong(ws) { - refresLogoutTimerOnPong(ws as ExSocketInterface); - }, close: (ws, code, message) => { const Client = (ws as ExSocketInterface); try { diff --git a/back/src/Enum/EnvironmentVariable.ts b/back/src/Enum/EnvironmentVariable.ts index 8be8d54d..3a2ac99e 100644 --- a/back/src/Enum/EnvironmentVariable.ts +++ b/back/src/Enum/EnvironmentVariable.ts @@ -10,7 +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 const SOCKET_IDLE_TIMER = parseInt(process.env.SOCKET_IDLE_TIMER as string) || 30; // maximum time (in second) without activity before a socket is closed export { SECRET_KEY, @@ -22,7 +22,6 @@ export { GROUP_RADIUS, ALLOW_ARTILLERY, CPU_OVERHEAT_THRESHOLD, - DEV_MODE, JITSI_URL, JITSI_ISS, SECRET_JITSI_KEY diff --git a/back/src/Model/Websocket/ExSocketInterface.ts b/back/src/Model/Websocket/ExSocketInterface.ts index e3d19138..c64a4952 100644 --- a/back/src/Model/Websocket/ExSocketInterface.ts +++ b/back/src/Model/Websocket/ExSocketInterface.ts @@ -25,8 +25,6 @@ export interface ExSocketInterface extends WebSocket, Identificable { emitInBatch: (payload: SubMessage) => void; batchedMessages: BatchMessage; batchTimeout: NodeJS.Timeout|null; - pingTimeout: NodeJS.Timeout|null; - pongTimeout: NodeJS.Timeout|null; disconnecting: boolean, tags: string[], textures: CharacterTexture[], diff --git a/back/src/Services/IoSocketHelpers.ts b/back/src/Services/IoSocketHelpers.ts index 1dbfa0bd..9c27c59a 100644 --- a/back/src/Services/IoSocketHelpers.ts +++ b/back/src/Services/IoSocketHelpers.ts @@ -1,6 +1,5 @@ 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); @@ -19,22 +18,6 @@ export function emitInBatch(socket: ExSocketInterface, payload: SubMessage): voi socket.batchTimeout = null; }, 100); } - - // If we send a message, we don't need to keep the connection alive - resetPing(socket); -} - -export function resetPing(ws: ExSocketInterface): void { - if (ws.pingTimeout) { - clearTimeout(ws.pingTimeout); - } - ws.pingTimeout = setTimeout(() => { - if (ws.disconnecting) { - return; - } - ws.ping(); - resetPing(ws); - }, 29000); } export function emitError(Client: ExSocketInterface, message: string): void { @@ -50,12 +33,3 @@ export function emitError(Client: ExSocketInterface, message: string): void { console.warn(message); } -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(); - }, pongMaxInterval); -} diff --git a/docker-compose.yaml b/docker-compose.yaml index 5deccb4d..482dfbcb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -78,7 +78,6 @@ services: ADMIN_API_TOKEN: "$ADMIN_API_TOKEN" JITSI_URL: $JITSI_URL JITSI_ISS: $JITSI_ISS - DEV_MODE: "1" volumes: - ./back:/usr/src/app labels: diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts index 19d011ff..b25e2d76 100644 --- a/front/src/Connexion/RoomConnection.ts +++ b/front/src/Connexion/RoomConnection.ts @@ -26,6 +26,7 @@ import { QueryJitsiJwtMessage, SendJitsiJwtMessage, CharacterLayerMessage, + PingMessage, SendUserMessage } from "../Messages/generated/messages_pb" @@ -42,6 +43,8 @@ import { } from "./ConnexionModels"; import {BodyResourceDescriptionInterface} from "../Phaser/Entity/body_character"; +const manualPingDelay = 20000; + export class RoomConnection implements RoomConnection { private readonly socket: WebSocket; private userId: number|null = null; @@ -84,7 +87,9 @@ export class RoomConnection implements RoomConnection { this.socket.binaryType = 'arraybuffer'; this.socket.onopen = (ev) => { - //console.log('WS connected'); + //we manually ping every 20s to not be logged out by the server, even when the game is in background. + const pingMessage = new PingMessage(); + setInterval(() => this.socket.send(pingMessage.serializeBinary().buffer), manualPingDelay); }; this.socket.onmessage = (messageEvent) => { diff --git a/messages/messages.proto b/messages/messages.proto index 89353825..6e0b47df 100644 --- a/messages/messages.proto +++ b/messages/messages.proto @@ -38,6 +38,10 @@ message CharacterLayerMessage { /*********** CLIENT TO SERVER MESSAGES *************/ +message PingMessage { + +} + message SetPlayerDetailsMessage { string name = 1; repeated string characterLayers = 2;