Merge pull request #121 from thecodingmachine/fix_mediatream_manage

Fix mediatream manage and connection server down
This commit is contained in:
David Négrier 2020-05-23 17:12:10 +02:00 committed by GitHub
commit 948284ae5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 92 additions and 53 deletions

View File

@ -15,21 +15,21 @@ export class AuthenticateController {
//permit to login on application. Return token to connect on Websocket IO. //permit to login on application. Return token to connect on Websocket IO.
login(){ login(){
// For now, let's completely forget the /login route. // For now, let's completely forget the /login route.
/*this.App.post("/login", (req: Request, res: Response) => { this.App.post("/login", (req: Request, res: Response) => {
let param = req.body; let param = req.body;
if(!param.email){ /*if(!param.name){
return res.status(BAD_REQUEST).send({ return res.status(BAD_REQUEST).send({
message: "email parameter is empty" message: "email parameter is empty"
}); });
} }*/
//TODO check user email for The Coding Machine game //TODO check user email for The Coding Machine game
let userId = uuid(); let userId = uuid();
let token = Jwt.sign({email: param.email, userId: userId}, SECRET_KEY, {expiresIn: '24h'}); let token = Jwt.sign({name: param.name, userId: userId}, SECRET_KEY, {expiresIn: '24h'});
return res.status(OK).send({ return res.status(OK).send({
token: token, token: token,
mapUrlStart: URL_ROOM_STARTED, mapUrlStart: URL_ROOM_STARTED,
userId: userId, userId: userId,
}); });
});*/ });
} }
} }

View File

@ -39,25 +39,42 @@ export class IoSocketController {
// Authentication with token. it will be decoded and stored in the socket. // Authentication with token. it will be decoded and stored in the socket.
// Completely commented for now, as we do not use the "/login" route at all. // Completely commented for now, as we do not use the "/login" route at all.
/*this.Io.use((socket: Socket, next) => { this.Io.use((socket: Socket, next) => {
if (!socket.handshake.query || !socket.handshake.query.token) { if (!socket.handshake.query || !socket.handshake.query.token) {
return next(new Error('Authentication error')); return next(new Error('Authentication error'));
} }
if(this.searchClientByToken(socket.handshake.query.token)){ if(this.searchClientByToken(socket.handshake.query.token)){
return next(new Error('Authentication error')); return next(new Error('Authentication error'));
} }
Jwt.verify(socket.handshake.query.token, SECRET_KEY, (err: JsonWebTokenError, tokenDecoded: object) => { Jwt.verify(socket.handshake.query.token, SECRET_KEY, (err: JsonWebTokenError, tokenDecoded: any) => {
if (err) { if (err) {
return next(new Error('Authentication error')); return next(new Error('Authentication error'));
} }
(socket as ExSocketInterface).token = tokenDecoded; (socket as ExSocketInterface).token = tokenDecoded;
(socket as ExSocketInterface).userId = tokenDecoded.userId;
next(); next();
}); });
});*/ });
this.ioConnection(); this.ioConnection();
} }
/**
*
* @param token
*/
searchClientByToken(token: string): ExSocketInterface | null {
let clients: Array<any> = Object.values(this.Io.sockets.sockets);
for (let i = 0; i < clients.length; i++) {
let client: ExSocketInterface = clients[i];
if (client.token !== token) {
continue
}
return client;
}
return null;
}
private sendUpdateGroupEvent(group: Group): void { private sendUpdateGroupEvent(group: Group): void {
// Let's get the room of the group. To do this, let's get anyone in the group and find its room. // Let's get the room of the group. To do this, let's get anyone in the group and find its room.
// Note: this is suboptimal // Note: this is suboptimal
@ -80,7 +97,8 @@ export class IoSocketController {
ioConnection() { ioConnection() {
this.Io.on(SockerIoEvent.CONNECTION, (socket: Socket) => { this.Io.on(SockerIoEvent.CONNECTION, (socket: Socket) => {
this.sockets.set(socket.id, socket as ExSocketInterface); let client : ExSocketInterface = socket as ExSocketInterface;
this.sockets.set(client.userId, client);
/*join-rom event permit to join one room. /*join-rom event permit to join one room.
message : message :
userId : user identification userId : user identification
@ -118,7 +136,7 @@ export class IoSocketController {
//add function to refresh position user in real time. //add function to refresh position user in real time.
//this.refreshUserPosition(Client); //this.refreshUserPosition(Client);
let messageUserJoined = new MessageUserJoined(Client.id, Client.name, Client.character, Client.position); let messageUserJoined = new MessageUserJoined(Client.userId, Client.name, Client.character, Client.position);
socket.to(roomId).emit(SockerIoEvent.JOIN_ROOM, messageUserJoined); socket.to(roomId).emit(SockerIoEvent.JOIN_ROOM, messageUserJoined);
@ -155,7 +173,7 @@ export class IoSocketController {
} }
world.updatePosition(Client, position); world.updatePosition(Client, position);
socket.to(Client.roomId).emit(SockerIoEvent.USER_MOVED, new MessageUserMoved(Client.id, Client.position)); socket.to(Client.roomId).emit(SockerIoEvent.USER_MOVED, new MessageUserMoved(Client.userId, Client.position));
} catch (e) { } catch (e) {
console.error('An error occurred on "user_position" event'); console.error('An error occurred on "user_position" event');
console.error(e); console.error(e);
@ -183,9 +201,8 @@ export class IoSocketController {
}); });
socket.on(SockerIoEvent.DISCONNECT, () => { socket.on(SockerIoEvent.DISCONNECT, () => {
let Client = (socket as ExSocketInterface);
try { try {
let Client = (socket as ExSocketInterface);
//leave room //leave room
this.leaveRoom(Client); this.leaveRoom(Client);
@ -201,7 +218,7 @@ export class IoSocketController {
console.error('An error occurred on "disconnect"'); console.error('An error occurred on "disconnect"');
console.error(e); console.error(e);
} }
this.sockets.delete(socket.id); this.sockets.delete(Client.userId);
}); });
// Let's send the user id to the user // Let's send the user id to the user
@ -209,7 +226,7 @@ export class IoSocketController {
let Client = (socket as ExSocketInterface); let Client = (socket as ExSocketInterface);
Client.name = playerDetails.name; Client.name = playerDetails.name;
Client.character = playerDetails.character; Client.character = playerDetails.character;
answerFn(socket.id); answerFn(Client.userId);
}); });
}); });
} }
@ -225,7 +242,7 @@ export class IoSocketController {
leaveRoom(Client : ExSocketInterface){ leaveRoom(Client : ExSocketInterface){
// leave previous room and world // leave previous room and world
if(Client.roomId){ if(Client.roomId){
Client.to(Client.roomId).emit(SockerIoEvent.USER_LEFT, Client.id); Client.to(Client.roomId).emit(SockerIoEvent.USER_LEFT, Client.userId);
//user leave previous world //user leave previous world
let world : World|undefined = this.Worlds.get(Client.roomId); let world : World|undefined = this.Worlds.get(Client.roomId);
@ -293,11 +310,11 @@ export class IoSocketController {
clients.forEach((client: ExSocketInterface, index: number) => { clients.forEach((client: ExSocketInterface, index: number) => {
let clientsId = clients.reduce((tabs: Array<any>, clientId: ExSocketInterface, indexClientId: number) => { let clientsId = clients.reduce((tabs: Array<any>, clientId: ExSocketInterface, indexClientId: number) => {
if (!clientId.id || clientId.id === client.id) { if (!clientId.userId || clientId.userId === client.userId) {
return tabs; return tabs;
} }
tabs.push({ tabs.push({
userId: clientId.id, userId: clientId.userId,
name: clientId.name, name: clientId.name,
initiator: index <= indexClientId initiator: index <= indexClientId
}); });

View File

@ -6,7 +6,7 @@ export interface ExSocketInterface extends Socket, Identificable {
token: any; token: any;
roomId: string; roomId: string;
webRtcRoomId: string; webRtcRoomId: string;
//userId: string; userId: string;
name: string; name: string;
character: string; character: string;
position: PointInterface; position: PointInterface;

View File

@ -1,3 +1,3 @@
export interface Identificable { export interface Identificable {
id: string; userId: string;
} }

View File

@ -53,8 +53,8 @@ export class World {
} }
public join(socket : Identificable, userPosition: PointInterface): void { public join(socket : Identificable, userPosition: PointInterface): void {
this.users.set(socket.id, { this.users.set(socket.userId, {
id: socket.id, id: socket.userId,
position: userPosition position: userPosition
}); });
// Let's call update position to trigger the join / leave room // Let's call update position to trigger the join / leave room
@ -62,18 +62,18 @@ export class World {
} }
public leave(user : Identificable){ public leave(user : Identificable){
let userObj = this.users.get(user.id); let userObj = this.users.get(user.userId);
if (userObj === undefined) { if (userObj === undefined) {
console.warn('User ', user.id, 'does not belong to world! It should!'); console.warn('User ', user.userId, 'does not belong to world! It should!');
} }
if (userObj !== undefined && typeof userObj.group !== 'undefined') { if (userObj !== undefined && typeof userObj.group !== 'undefined') {
this.leaveGroup(userObj); this.leaveGroup(userObj);
} }
this.users.delete(user.id); this.users.delete(user.userId);
} }
public updatePosition(socket : Identificable, userPosition: PointInterface): void { public updatePosition(socket : Identificable, userPosition: PointInterface): void {
let user = this.users.get(socket.id); let user = this.users.get(socket.userId);
if(typeof user === 'undefined') { if(typeof user === 'undefined') {
return; return;
} }

View File

@ -15,19 +15,19 @@ describe("World", () => {
let world = new World(connect, disconnect, 160, 160, () => {}, () => {}); let world = new World(connect, disconnect, 160, 160, () => {}, () => {});
world.join({ id: "foo" }, new Point(100, 100)); world.join({ userId: "foo" }, new Point(100, 100));
world.join({ id: "bar" }, new Point(500, 100)); world.join({ userId: "bar" }, new Point(500, 100));
world.updatePosition({ id: "bar" }, new Point(261, 100)); world.updatePosition({ userId: "bar" }, new Point(261, 100));
expect(connectCalledNumber).toBe(0); expect(connectCalledNumber).toBe(0);
world.updatePosition({ id: "bar" }, new Point(101, 100)); world.updatePosition({ userId: "bar" }, new Point(101, 100));
expect(connectCalledNumber).toBe(2); expect(connectCalledNumber).toBe(2);
world.updatePosition({ id: "bar" }, new Point(102, 100)); world.updatePosition({ userId: "bar" }, new Point(102, 100));
expect(connectCalledNumber).toBe(2); expect(connectCalledNumber).toBe(2);
}); });
@ -42,19 +42,19 @@ describe("World", () => {
let world = new World(connect, disconnect, 160, 160, () => {}, () => {}); let world = new World(connect, disconnect, 160, 160, () => {}, () => {});
world.join({ id: "foo" }, new Point(100, 100)); world.join({ userId: "foo" }, new Point(100, 100));
world.join({ id: "bar" }, new Point(200, 100)); world.join({ userId: "bar" }, new Point(200, 100));
expect(connectCalled).toBe(true); expect(connectCalled).toBe(true);
connectCalled = false; connectCalled = false;
// baz joins at the outer limit of the group // baz joins at the outer limit of the group
world.join({ id: "baz" }, new Point(311, 100)); world.join({ userId: "baz" }, new Point(311, 100));
expect(connectCalled).toBe(false); expect(connectCalled).toBe(false);
world.updatePosition({ id: "baz" }, new Point(309, 100)); world.updatePosition({ userId: "baz" }, new Point(309, 100));
expect(connectCalled).toBe(true); expect(connectCalled).toBe(true);
}); });
@ -71,18 +71,18 @@ describe("World", () => {
let world = new World(connect, disconnect, 160, 160, () => {}, () => {}); let world = new World(connect, disconnect, 160, 160, () => {}, () => {});
world.join({ id: "foo" }, new Point(100, 100)); world.join({ userId: "foo" }, new Point(100, 100));
world.join({ id: "bar" }, new Point(259, 100)); world.join({ userId: "bar" }, new Point(259, 100));
expect(connectCalled).toBe(true); expect(connectCalled).toBe(true);
expect(disconnectCallNumber).toBe(0); expect(disconnectCallNumber).toBe(0);
world.updatePosition({ id: "bar" }, new Point(100+160+160+1, 100)); world.updatePosition({ userId: "bar" }, new Point(100+160+160+1, 100));
expect(disconnectCallNumber).toBe(2); expect(disconnectCallNumber).toBe(2);
world.updatePosition({ id: "bar" }, new Point(262, 100)); world.updatePosition({ userId: "bar" }, new Point(262, 100));
expect(disconnectCallNumber).toBe(2); expect(disconnectCallNumber).toBe(2);
}); });

View File

@ -165,25 +165,20 @@ export class Connexion implements ConnexionInterface {
createConnexion(name: string, characterSelected: string): Promise<ConnexionInterface> { createConnexion(name: string, characterSelected: string): Promise<ConnexionInterface> {
this.name = name; this.name = name;
this.character = characterSelected; this.character = characterSelected;
/*return Axios.post(`${API_URL}/login`, {email: this.email}) return Axios.post(`${API_URL}/login`, {name: name})
.then((res) => { .then((res) => {
this.token = res.data.token; this.token = res.data.token;
this.userId = res.data.userId;*/
this.socket = SocketIo(`${API_URL}`, { this.socket = SocketIo(`${API_URL}`, {
/*query: { query: {
token: this.token token: this.token
}*/ }
}); });
return this.connectSocketServer(); return this.connectSocketServer();
/* return res.data;
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.error(err);
throw err; throw err;
});*/ });
} }
/** /**

View File

@ -1,12 +1,11 @@
import {GameManager, gameManager, HasMovedEvent, MapObject, StatusGameManagerEnum} from "./GameManager"; import {GameManager, gameManager, HasMovedEvent} from "./GameManager";
import { import {
GroupCreatedUpdatedMessageInterface, GroupCreatedUpdatedMessageInterface,
MessageUserJoined,
MessageUserMovedInterface, MessageUserMovedInterface,
MessageUserPositionInterface MessageUserPositionInterface
} from "../../Connexion"; } from "../../Connexion";
import {CurrentGamerInterface, GamerInterface, hasMovedEventName, Player} from "../Player/Player"; import {CurrentGamerInterface, GamerInterface, hasMovedEventName, Player} from "../Player/Player";
import { DEBUG_MODE, RESOLUTION, ROOM, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable"; import { DEBUG_MODE, ZOOM_LEVEL} from "../../Enum/EnvironmentVariable";
import {ITiledMap, ITiledMapLayer, ITiledTileSet} from "../Map/ITiledMap"; import {ITiledMap, ITiledMapLayer, ITiledTileSet} from "../Map/ITiledMap";
import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter"; import {PLAYER_RESOURCES} from "../Entity/PlayableCaracter";
import Texture = Phaser.Textures.Texture; import Texture = Phaser.Textures.Texture;
@ -410,6 +409,14 @@ export class GameScene extends Phaser.Scene {
* Create new player * Create new player
*/ */
public addPlayer(addPlayerData : AddPlayerInterface) : void{ public addPlayer(addPlayerData : AddPlayerInterface) : void{
//check if exist player, if exist, move position
if(this.MapPlayersByKey.has(addPlayerData.userId)){
this.updatePlayerPosition({
userId: addPlayerData.userId,
position: addPlayerData.position
});
return;
}
//initialise player //initialise player
let player = new Player( let player = new Player(
addPlayerData.userId, addPlayerData.userId,

View File

@ -141,9 +141,9 @@ export class SimplePeer implements SimplePeerInterface{
this.stream(user.userId, stream); this.stream(user.userId, stream);
}); });
this.PeerConnexionArray.get(user.userId).on('track', (track: MediaStreamTrack, stream: MediaStream) => { /*this.PeerConnexionArray.get(user.userId).on('track', (track: MediaStreamTrack, stream: MediaStream) => {
this.stream(user.userId, stream); this.stream(user.userId, stream);
}); });*/
this.PeerConnexionArray.get(user.userId).on('close', () => { this.PeerConnexionArray.get(user.userId).on('close', () => {
this.closeConnexion(user.userId); this.closeConnexion(user.userId);
@ -157,6 +157,13 @@ export class SimplePeer implements SimplePeerInterface{
console.info(`connect => ${user.userId}`); console.info(`connect => ${user.userId}`);
}); });
this.PeerConnexionArray.get(user.userId).on('data', (chunk: Buffer) => {
let data = JSON.parse(chunk.toString('utf8'));
if(data.type === "stream"){
this.stream(user.userId, data.stream);
}
});
this.addMedia(user.userId); this.addMedia(user.userId);
} }
@ -205,6 +212,11 @@ export class SimplePeer implements SimplePeerInterface{
* @param stream * @param stream
*/ */
private stream(userId : any, stream: MediaStream) { private stream(userId : any, stream: MediaStream) {
if(!stream){
this.MediaManager.disabledVideoByUserId(userId);
this.MediaManager.disabledMicrophoneByUserId(userId);
return;
}
this.MediaManager.addStreamRemoteVideo(userId, stream); this.MediaManager.addStreamRemoteVideo(userId, stream);
} }
@ -216,6 +228,14 @@ export class SimplePeer implements SimplePeerInterface{
try { try {
let transceiver : any = null; let transceiver : any = null;
if(!this.MediaManager.localStream){ if(!this.MediaManager.localStream){
//send fake signal
if(!this.PeerConnexionArray.has(userId)){
return;
}
this.PeerConnexionArray.get(userId).write(new Buffer(JSON.stringify({
type: "stream",
stream: null
})));
return; return;
} }
this.MediaManager.localStream.getTracks().forEach( this.MediaManager.localStream.getTracks().forEach(