From ec297e3912da97cf751e1806bf37e92fd163690f Mon Sep 17 00:00:00 2001 From: gparant Date: Wed, 13 May 2020 20:22:42 +0200 Subject: [PATCH] Auto-reconnect --- back/src/Controller/IoSocketController.ts | 18 +++++++ front/dist/index.html | 2 +- front/dist/resources/style/style.css | 22 ++++++++ front/src/Connexion.ts | 62 ++++++++++++++++++----- front/src/Logger/MessageUI.ts | 27 ++++++++++ front/src/Phaser/Game/GameScene.ts | 1 - front/src/Phaser/Login/LogincScene.ts | 1 - 7 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 front/src/Logger/MessageUI.ts diff --git a/back/src/Controller/IoSocketController.ts b/back/src/Controller/IoSocketController.ts index 672fbcac..60bbe6ad 100644 --- a/back/src/Controller/IoSocketController.ts +++ b/back/src/Controller/IoSocketController.ts @@ -37,6 +37,9 @@ export class IoSocketController { if (!socket.handshake.query || !socket.handshake.query.token) { return next(new Error('Authentication error')); } + if(this.searchClientByToken(socket.handshake.query.token)){ + return next(new Error('Authentication error')); + } Jwt.verify(socket.handshake.query.token, SECRET_KEY, (err: JsonWebTokenError, tokenDecoded: object) => { if (err) { return next(new Error('Authentication error')); @@ -206,6 +209,21 @@ export class IoSocketController { return null; } + /** + * @param userId + */ + searchClientByToken(userId: string): ExSocketInterface | null { + let clients: Array = Object.values(this.Io.sockets.sockets); + for (let i = 0; i < clients.length; i++) { + let client: ExSocketInterface = clients[i]; + if (client.userId !== userId) { + continue + } + return client; + } + return null; + } + /** * * @param Client: ExSocketInterface diff --git a/front/dist/index.html b/front/dist/index.html index 51d52705..0815a882 100644 --- a/front/dist/index.html +++ b/front/dist/index.html @@ -9,7 +9,7 @@ Document - +
diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index bfac76b1..8c5975a0 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -1,6 +1,28 @@ body{ overflow: hidden; } +body .message-info{ + width: 20%; + height: auto; + min-height: 30px; + position: absolute; + top: 5px; + left: 40%; + padding-top: 10px; + text-align: center; +} +body .message-info.error{ + background: red; +} +body .message-info.success{ + background: green; +} +body .message-info.info{ + background: dodgerblue; +} +body .message-info.warning{ + background: #ffa500d6; +} video{ -webkit-transform: scaleX(-1); transform: scaleX(-1); diff --git a/front/src/Connexion.ts b/front/src/Connexion.ts index f7d1e7db..d6d37025 100644 --- a/front/src/Connexion.ts +++ b/front/src/Connexion.ts @@ -4,6 +4,7 @@ const SocketIo = require('socket.io-client'); import Axios from "axios"; import {API_URL} from "./Enum/EnvironmentVariable"; import {getMapKeyByUrl} from "./Phaser/Login/LogincScene"; +import {MessageUI} from "./Logger/MessageUI"; enum EventMessage{ WEBRTC_SIGNAL = "webrtc-signal", @@ -15,6 +16,9 @@ enum EventMessage{ WEBRTC_DISCONNECT = "webrtc-disconect", GROUP_CREATE_UPDATE = "group-create-update", GROUP_DELETE = "group-delete", + + CONNECT_ERROR = "connect_error", + RECONNECT = "reconnect" } class Message { @@ -169,6 +173,8 @@ export class Connexion implements ConnexionInterface { GameManager: GameManager; + lastPositionShared: MessageUserPosition = null; + constructor(email : string, GameManager: GameManager) { this.email = email; this.GameManager = GameManager; @@ -189,18 +195,7 @@ export class Connexion implements ConnexionInterface { } }); - //join the room - //this.joinARoom(this.startedRoom, characterSelected); - - //share your first position - //this.sharePosition(0, 0, characterSelected, this.startedRoom); - - this.positionOfAllUser(); - - this.errorMessage(); - - this.groupUpdatedOrCreated(); - this.groupDeleted(); + this.connectSocketServer(); return res.data; }) @@ -210,6 +205,37 @@ export class Connexion implements ConnexionInterface { }); } + /** + * + * @param character + */ + connectSocketServer(character : string = null){ + //if try to reconnect with last position + if(this.lastPositionShared) { + //join the room + this.joinARoom( + this.lastPositionShared.roomId, + this.lastPositionShared.character + ); + + //share your first position + this.sharePosition( + this.lastPositionShared ? this.lastPositionShared.position.x : 0, + this.lastPositionShared ? this.lastPositionShared.position.y : 0, + this.lastPositionShared.character, + this.lastPositionShared.roomId, + this.lastPositionShared.position.direction + ); + } + + //listen event + this.positionOfAllUser(); + this.disconnectServer(); + this.errorMessage(); + this.groupUpdatedOrCreated(); + this.groupDeleted(); + } + //TODO add middleware with access token to secure api loadMaps() : Promise { return Axios.get(`${API_URL}/maps`) @@ -256,6 +282,7 @@ export class Connexion implements ConnexionInterface { this.email, character ); + this.lastPositionShared = messageUserPosition; this.socket.emit(EventMessage.USER_POSITION, messageUserPosition.toString()); } @@ -319,6 +346,17 @@ export class Connexion implements ConnexionInterface { }) } + disconnectServer(): void { + this.socket.on(EventMessage.CONNECT_ERROR, () => { + MessageUI.warningMessage("Trying to connect!"); + }); + + this.socket.on(EventMessage.RECONNECT, () => { + MessageUI.removeMessage(); + this.connectSocketServer(); + }); + } + disconnectMessage(callback: Function): void { this.socket.on(EventMessage.WEBRTC_DISCONNECT, callback); } diff --git a/front/src/Logger/MessageUI.ts b/front/src/Logger/MessageUI.ts new file mode 100644 index 00000000..a73c2418 --- /dev/null +++ b/front/src/Logger/MessageUI.ts @@ -0,0 +1,27 @@ +export class MessageUI { + + static warningMessage(text: string){ + this.removeMessage(); + let body = document.getElementById("body"); + body.insertAdjacentHTML('afterbegin', ` +
+ ${text} +
+ `); + } + + static removeMessage(id : string = null) { + if(!id){ + let messages = document.getElementsByClassName("message-info"); + for (let i = 0; i < messages.length; i++){ + messages.item(i).remove(); + } + return; + } + let previousElement = document.getElementById(id); + if (!previousElement) { + return; + } + previousElement.remove(); + } +} \ No newline at end of file diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 701cbe31..7b32e3ef 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -185,7 +185,6 @@ export class GameScene extends Phaser.Scene implements GameSceneInterface, Creat // TODO: eventually compute a relative URL let absoluteExitSceneUrl = new URL(exitSceneUrl, this.MapUrlFile).href; - console.log('absoluteExitSceneUrl ', absoluteExitSceneUrl); let exitSceneKey = gameManager.loadMap(absoluteExitSceneUrl, this.scene); let tiles : any = layer.data; diff --git a/front/src/Phaser/Login/LogincScene.ts b/front/src/Phaser/Login/LogincScene.ts index 3136060c..ea21e9f5 100644 --- a/front/src/Phaser/Login/LogincScene.ts +++ b/front/src/Phaser/Login/LogincScene.ts @@ -13,7 +13,6 @@ export function getMapKeyByUrl(mapUrlStart: string){ // FIXME: the key should be computed from the full URL of the map. let startPos = mapUrlStart.indexOf('://')+3; let endPos = mapUrlStart.indexOf(".json"); - console.log('MAP KEY '+mapUrlStart.substring(startPos, endPos)); return mapUrlStart.substring(startPos, endPos);