Share players position using Socket.IO
authorgparant <g.parant@thecodingmachine.com>
Sat, 4 Apr 2020 17:25:08 +0000 (19:25 +0200)
committergparant <g.parant@thecodingmachine.com>
Sat, 4 Apr 2020 17:25:08 +0000 (19:25 +0200)
 - I stocked information user (id, room and position) in socket client.
 - I created function to send all information every few 10 milliseconds.

Note : when the front will be available, we must check the performance of back server.

back/src/Controller/AuthenticateController.ts
back/src/Controller/IoSocketController.ts
back/src/Enum/EnvironmentVariable.ts
back/src/Model/Websocket/ExSocketInterface.ts

index 01985b6a397e0cb0e7075f979f1dd313a2c25ca3..c810ea8a292531dd0dba3b77290a479e54929dbe 100644 (file)
@@ -1,7 +1,7 @@
 import {Application, Request, Response} from "express";
 import Jwt, {JsonWebTokenError} from "jsonwebtoken";
 import {BAD_REQUEST, OK} from "http-status-codes";
-import {SECRET_KEY} from "../Enum/EnvironmentVariable";
+import {SECRET_KEY, ROOM} from "../Enum/EnvironmentVariable";
 
 export class AuthenticateController{
     App : Application;
@@ -21,7 +21,7 @@ export class AuthenticateController{
                 });
             }
             //TODO check user email for The Coding Machine game
-            let token = Jwt.sign({email: param.email}, SECRET_KEY, {expiresIn: '24h'});
+            let token = Jwt.sign({email: param.email, roomId: ROOM}, SECRET_KEY, {expiresIn: '24h'});
             return res.status(OK).send({token: token});
         });
     }
index 5dbacdac97d2bed3457bdbcdfa54bcb14f1cf83f..696f3267762194c51134a3fe2de2a0776e0bd69b 100644 (file)
@@ -26,6 +26,7 @@ export class IoSocketController{
         });
 
         this.ioConnection();
+        this.shareUsersPosition();
     }
 
     ioConnection() {
@@ -38,7 +39,6 @@ export class IoSocketController{
                         x: user x position on map
                         y: user y position on map
             */
-
             socket.on('join-room', (message : string) => {
                 let messageUserPosition = this.hydrateMessageReceive(message);
                 if(messageUserPosition instanceof Error){
@@ -47,7 +47,7 @@ export class IoSocketController{
                 //join user in room
                 socket.join(messageUserPosition.roomId);
                 // sending to all clients in room except sender
-                this.saveUserPosition((socket as ExSocketInterface), messageUserPosition);
+                this.saveUserInformation((socket as ExSocketInterface), messageUserPosition);
                 socket.to(messageUserPosition.roomId).emit('join-room', messageUserPosition.toString());
             });
 
@@ -57,15 +57,17 @@ export class IoSocketController{
                     return socket.emit("message-error", JSON.stringify({message: messageUserPosition.message}));
                 }
                 // sending to all clients in room except sender
-                this.saveUserPosition((socket as ExSocketInterface), messageUserPosition);
+                this.saveUserInformation((socket as ExSocketInterface), messageUserPosition);
                 socket.to(messageUserPosition.roomId).emit('join-room', messageUserPosition.toString());
             });
         });
     }
 
     //permit to save user position in socket
-    saveUserPosition(socket : ExSocketInterface, message : MessageUserPosition){
+    saveUserInformation(socket : ExSocketInterface, message : MessageUserPosition){
         socket.position = message.position;
+        socket.roomId = message.roomId;
+        socket.userId = message.userId;
     }
 
     //Hydrate and manage error
@@ -77,4 +79,61 @@ export class IoSocketController{
             return new Error(err);
         }
     }
+
+    /** permit to share user position
+        ** users position will send in event 'user-position'
+        ** The data sent is an array with information for each user :
+        [
+          {
+            userId: <string>,
+            roomId: <string>,
+            position: {
+                x : <number>,
+                y : <number>
+            }
+          },
+          ...
+        ]
+     **/
+    seTimeOutInProgress : any = null;
+    shareUsersPosition(){
+        if(!this.seTimeOutInProgress) {
+            clearTimeout(this.seTimeOutInProgress);
+        }
+        let clients = this.Io.clients();
+        let socketsKey = Object.keys(this.Io.clients().sockets);
+
+        //create mapping with all users in all rooms
+        let mapPositionUserByRoom = new Map();
+        for(let i = 0; i < socketsKey.length; i++){
+            let socket = clients.sockets[socketsKey[i]];
+            if(!(socket as ExSocketInterface).position){
+                continue;
+            }
+            let data = {
+                userId : (socket as ExSocketInterface).userId,
+                roomId : (socket as ExSocketInterface).roomId,
+                position : (socket as ExSocketInterface).position,
+            };
+            let dataArray = <any>[];
+            if(mapPositionUserByRoom.get(data.roomId)){
+                dataArray = mapPositionUserByRoom.get(data.roomId);
+                dataArray.push(data);
+            }else{
+                dataArray = [data];
+            }
+            mapPositionUserByRoom.set(data.roomId, dataArray);
+        }
+
+        //send for each room, all data of position user
+        let arrayMap = Array.from(mapPositionUserByRoom);
+        arrayMap.forEach((value) => {
+            let roomId = value[0];
+            let data = value[1];
+            this.Io.in(roomId).emit('user-position', JSON.stringify(data));
+        });
+        this.seTimeOutInProgress = setTimeout(() => {
+            this.shareUsersPosition();
+        }, 10);
+    }
 }
\ No newline at end of file
index 27f56d78919f3cd013c010da97862c25f0272601..f795bf908786efcae2e1386cc4a3663a2387f202 100644 (file)
@@ -1,5 +1,7 @@
 const SECRET_KEY = process.env.SECRET_KEY || "THECODINGMACHINE_SECRET_KEY";
+const ROOM = process.env.ROOM || "THECODINGMACHINE";
 
 export {
-    SECRET_KEY
+    SECRET_KEY,
+    ROOM
 }
\ No newline at end of file
index 51df9258c48a8b4e87b16bb2450f1fcd0c4458d8..095d3cbc0ebda4d7f53c39dc1d53e11bc360f830 100644 (file)
@@ -2,6 +2,8 @@ import {Socket} from "socket.io";
 import {PointInterface} from "./PointInterface";
 
 export interface ExSocketInterface extends Socket {
-    token: object;
+    token: any;
+    roomId: string;
+    userId: string;
     position: PointInterface;
 }
\ No newline at end of file