|
|
|
@@ -37,7 +37,12 @@ import {
|
|
|
|
|
ErrorMessage,
|
|
|
|
|
RoomJoinedMessage,
|
|
|
|
|
ItemStateMessage,
|
|
|
|
|
ServerToClientMessage, SetUserIdMessage, SilentMessage
|
|
|
|
|
ServerToClientMessage,
|
|
|
|
|
SetUserIdMessage,
|
|
|
|
|
SilentMessage,
|
|
|
|
|
WebRtcSignalToClientMessage,
|
|
|
|
|
WebRtcSignalToServerMessage,
|
|
|
|
|
WebRtcStartMessage, WebRtcDisconnectMessage
|
|
|
|
|
} from "../Messages/generated/messages_pb";
|
|
|
|
|
import {UserMovesMessage} from "../Messages/generated/messages_pb";
|
|
|
|
|
import Direction = PositionMessage.Direction;
|
|
|
|
@@ -186,7 +191,7 @@ export class IoSocketController {
|
|
|
|
|
/* Options */
|
|
|
|
|
//compression: uWS.SHARED_COMPRESSOR,
|
|
|
|
|
maxPayloadLength: 16 * 1024 * 1024,
|
|
|
|
|
idleTimeout: 10,
|
|
|
|
|
//idleTimeout: 10,
|
|
|
|
|
/* Handlers */
|
|
|
|
|
open: (ws) => {
|
|
|
|
|
this.authenticate(ws);
|
|
|
|
@@ -222,6 +227,10 @@ export class IoSocketController {
|
|
|
|
|
this.handleSilentMessage(client, message.getSilentmessage() as SilentMessage);
|
|
|
|
|
} else if (message.hasItemeventmessage()) {
|
|
|
|
|
this.handleItemEvent(client, message.getItemeventmessage() as ItemEventMessage);
|
|
|
|
|
} else if (message.hasWebrtcsignaltoservermessage()) {
|
|
|
|
|
this.emitVideo(client, message.getWebrtcsignaltoservermessage() as WebRtcSignalToServerMessage)
|
|
|
|
|
} else if (message.hasWebrtcscreensharingsignaltoservermessage()) {
|
|
|
|
|
this.emitScreenSharing(client, message.getWebrtcscreensharingsignaltoservermessage() as WebRtcSignalToServerMessage)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ok is false if backpressure was built up, wait for drain */
|
|
|
|
@@ -282,7 +291,7 @@ export class IoSocketController {
|
|
|
|
|
serverToClientMessage.setErrormessage(errorMessage);
|
|
|
|
|
|
|
|
|
|
if (!Client.disconnecting) {
|
|
|
|
|
Client.send(serverToClientMessage.serializeBinary().buffer);
|
|
|
|
|
Client.send(serverToClientMessage.serializeBinary().buffer, true);
|
|
|
|
|
}
|
|
|
|
|
console.warn(message);
|
|
|
|
|
}
|
|
|
|
@@ -496,40 +505,44 @@ export class IoSocketController {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
emitVideo(socket: ExSocketInterface, data: unknown){
|
|
|
|
|
if (!isWebRtcSignalMessageInterface(data)) {
|
|
|
|
|
socket.emit(SocketIoEvent.MESSAGE_ERROR, {message: 'Invalid WEBRTC_SIGNAL message.'});
|
|
|
|
|
console.warn('Invalid WEBRTC_SIGNAL message received: ', data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
emitVideo(socket: ExSocketInterface, data: WebRtcSignalToServerMessage): void {
|
|
|
|
|
//send only at user
|
|
|
|
|
const client = this.sockets.get(data.receiverId);
|
|
|
|
|
const client = this.sockets.get(data.getReceiverid());
|
|
|
|
|
if (client === undefined) {
|
|
|
|
|
console.warn("While exchanging a WebRTC signal: client with id ", data.receiverId, " does not exist. This might be a race condition.");
|
|
|
|
|
console.warn("While exchanging a WebRTC signal: client with id ", data.getReceiverid(), " does not exist. This might be a race condition.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return client.emit(SocketIoEvent.WEBRTC_SIGNAL, {
|
|
|
|
|
userId: socket.userId,
|
|
|
|
|
signal: data.signal
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const webrtcSignalToClient = new WebRtcSignalToClientMessage();
|
|
|
|
|
webrtcSignalToClient.setUserid(socket.userId);
|
|
|
|
|
webrtcSignalToClient.setSignal(data.getSignal());
|
|
|
|
|
|
|
|
|
|
const serverToClientMessage = new ServerToClientMessage();
|
|
|
|
|
serverToClientMessage.setWebrtcsignaltoclientmessage(webrtcSignalToClient);
|
|
|
|
|
|
|
|
|
|
if (!client.disconnecting) {
|
|
|
|
|
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
emitScreenSharing(socket: ExSocketInterface, data: unknown){
|
|
|
|
|
if (!isWebRtcSignalMessageInterface(data)) {
|
|
|
|
|
socket.emit(SocketIoEvent.MESSAGE_ERROR, {message: 'Invalid WEBRTC_SCREEN_SHARING message.'});
|
|
|
|
|
console.warn('Invalid WEBRTC_SCREEN_SHARING message received: ', data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
emitScreenSharing(socket: ExSocketInterface, data: WebRtcSignalToServerMessage): void {
|
|
|
|
|
//send only at user
|
|
|
|
|
const client = this.sockets.get(data.receiverId);
|
|
|
|
|
const client = this.sockets.get(data.getReceiverid());
|
|
|
|
|
if (client === undefined) {
|
|
|
|
|
console.warn("While exchanging a WEBRTC_SCREEN_SHARING signal: client with id ", data.receiverId, " does not exist. This might be a race condition.");
|
|
|
|
|
console.warn("While exchanging a WEBRTC_SCREEN_SHARING signal: client with id ", data.getReceiverid(), " does not exist. This might be a race condition.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
return client.emit(SocketIoEvent.WEBRTC_SCREEN_SHARING_SIGNAL, {
|
|
|
|
|
userId: socket.userId,
|
|
|
|
|
signal: data.signal
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const webrtcSignalToClient = new WebRtcSignalToClientMessage();
|
|
|
|
|
webrtcSignalToClient.setUserid(socket.userId);
|
|
|
|
|
webrtcSignalToClient.setSignal(data.getSignal());
|
|
|
|
|
|
|
|
|
|
const serverToClientMessage = new ServerToClientMessage();
|
|
|
|
|
serverToClientMessage.setWebrtcscreensharingsignaltoclientmessage(webrtcSignalToClient);
|
|
|
|
|
|
|
|
|
|
if (!client.disconnecting) {
|
|
|
|
|
client.send(serverToClientMessage.serializeBinary().buffer, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
searchClientByIdOrFail(userId: number): ExSocketInterface {
|
|
|
|
@@ -571,9 +584,9 @@ export class IoSocketController {
|
|
|
|
|
//check and create new world for a room
|
|
|
|
|
let world = this.Worlds.get(roomId)
|
|
|
|
|
if(world === undefined){
|
|
|
|
|
world = new World((user1: number, group: Group) => {
|
|
|
|
|
this.connectedUser(user1, group);
|
|
|
|
|
}, (user1: number, group: Group) => {
|
|
|
|
|
world = new World((user1: User, group: Group) => {
|
|
|
|
|
this.joinWebRtcRoom(user1, group);
|
|
|
|
|
}, (user1: User, group: Group) => {
|
|
|
|
|
this.disConnectedUser(user1, group);
|
|
|
|
|
}, MINIMUM_DISTANCE, GROUP_RADIUS, (thing: Movable, listener: User) => {
|
|
|
|
|
const clientListener = this.searchClientByIdOrFail(listener.id);
|
|
|
|
@@ -677,20 +690,49 @@ export class IoSocketController {
|
|
|
|
|
emitInBatch(client, subMessage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param socket
|
|
|
|
|
* @param roomId
|
|
|
|
|
*/
|
|
|
|
|
joinWebRtcRoom(socket: ExSocketInterface, roomId: string) {
|
|
|
|
|
|
|
|
|
|
// TODO: REBUILD THIS
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* if (socket.webRtcRoomId === roomId) {
|
|
|
|
|
joinWebRtcRoom(user: User, group: Group) {
|
|
|
|
|
/*const roomId: string = "webrtcroom"+group.getId();
|
|
|
|
|
if (user.socket.webRtcRoomId === roomId) {
|
|
|
|
|
return;
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
// TODO: joinWebRtcRoom will be trigerred twice when joining the first time! Maybe we should fix the GROUP constructor to trigger only one event
|
|
|
|
|
console.log('joinWebRtcRoom FOR '+user.socket.name+" "+user.socket.userId);
|
|
|
|
|
for (const otherUser of group.getUsers()) {
|
|
|
|
|
if (user === otherUser) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Let's send 2 messages: one to the user joining the group and one to the other user
|
|
|
|
|
const webrtcStartMessage1 = new WebRtcStartMessage();
|
|
|
|
|
webrtcStartMessage1.setUserid(otherUser.id);
|
|
|
|
|
webrtcStartMessage1.setName(otherUser.socket.name);
|
|
|
|
|
webrtcStartMessage1.setInitiator(true);
|
|
|
|
|
|
|
|
|
|
const serverToClientMessage1 = new ServerToClientMessage();
|
|
|
|
|
serverToClientMessage1.setWebrtcstartmessage(webrtcStartMessage1);
|
|
|
|
|
|
|
|
|
|
if (!user.socket.disconnecting) {
|
|
|
|
|
user.socket.send(serverToClientMessage1.serializeBinary().buffer, true);
|
|
|
|
|
console.log('Sending webrtcstart initiator to '+user.socket.userId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const webrtcStartMessage2 = new WebRtcStartMessage();
|
|
|
|
|
webrtcStartMessage2.setUserid(user.id);
|
|
|
|
|
webrtcStartMessage2.setName(user.socket.name);
|
|
|
|
|
webrtcStartMessage2.setInitiator(false);
|
|
|
|
|
|
|
|
|
|
const serverToClientMessage2 = new ServerToClientMessage();
|
|
|
|
|
serverToClientMessage2.setWebrtcstartmessage(webrtcStartMessage2);
|
|
|
|
|
|
|
|
|
|
if (!otherUser.socket.disconnecting) {
|
|
|
|
|
otherUser.socket.send(serverToClientMessage2.serializeBinary().buffer, true);
|
|
|
|
|
console.log('Sending webrtcstart to '+otherUser.socket.userId)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
socket.join(roomId);
|
|
|
|
|
|
|
|
|
|
/* socket.join(roomId);
|
|
|
|
|
socket.webRtcRoomId = roomId;
|
|
|
|
|
//if two persons in room share
|
|
|
|
|
if (this.Io.sockets.adapter.rooms[roomId].length < 2) {
|
|
|
|
@@ -737,43 +779,49 @@ export class IoSocketController {
|
|
|
|
|
]
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
//connected user
|
|
|
|
|
connectedUser(userId: number, group: Group) {
|
|
|
|
|
/*let Client = this.sockets.get(userId);
|
|
|
|
|
if (Client === undefined) {
|
|
|
|
|
return;
|
|
|
|
|
}*/
|
|
|
|
|
const Client = this.searchClientByIdOrFail(userId);
|
|
|
|
|
this.joinWebRtcRoom(Client, "webrtcroom"+group.getId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//disconnect user
|
|
|
|
|
disConnectedUser(userId: number, group: Group) {
|
|
|
|
|
// TODO: rebuild this
|
|
|
|
|
return;
|
|
|
|
|
disConnectedUser(user: User, group: Group) {
|
|
|
|
|
|
|
|
|
|
const Client = this.searchClientByIdOrFail(userId);
|
|
|
|
|
Client.to("webrtcroom"+group.getId()).emit(SocketIoEvent.WEBRTC_DISCONNECT, {
|
|
|
|
|
userId: userId
|
|
|
|
|
});
|
|
|
|
|
const Client = user.socket;
|
|
|
|
|
|
|
|
|
|
// Most of the time, sending a disconnect event to one of the players is enough (the player will close the connection
|
|
|
|
|
// which will be shut for the other player).
|
|
|
|
|
// However! In the rare case where the WebRTC connection is not yet established, if we close the connection on one of the player,
|
|
|
|
|
// the other player will try connecting until a timeout happens (during this time, the connection icon will be displayed for nothing).
|
|
|
|
|
// So we also send the disconnect event to the other player.
|
|
|
|
|
for (const user of group.getUsers()) {
|
|
|
|
|
Client.emit(SocketIoEvent.WEBRTC_DISCONNECT, {
|
|
|
|
|
userId: user.id
|
|
|
|
|
});
|
|
|
|
|
for (const otherUser of group.getUsers()) {
|
|
|
|
|
if (user === otherUser) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const webrtcDisconnectMessage1 = new WebRtcDisconnectMessage();
|
|
|
|
|
webrtcDisconnectMessage1.setUserid(user.id);
|
|
|
|
|
|
|
|
|
|
const serverToClientMessage1 = new ServerToClientMessage();
|
|
|
|
|
serverToClientMessage1.setWebrtcdisconnectmessage(webrtcDisconnectMessage1);
|
|
|
|
|
|
|
|
|
|
if (!otherUser.socket.disconnecting) {
|
|
|
|
|
otherUser.socket.send(serverToClientMessage1.serializeBinary().buffer, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const webrtcDisconnectMessage2 = new WebRtcDisconnectMessage();
|
|
|
|
|
webrtcDisconnectMessage2.setUserid(otherUser.id);
|
|
|
|
|
|
|
|
|
|
const serverToClientMessage2 = new ServerToClientMessage();
|
|
|
|
|
serverToClientMessage2.setWebrtcdisconnectmessage(webrtcDisconnectMessage2);
|
|
|
|
|
|
|
|
|
|
if (!user.socket.disconnecting) {
|
|
|
|
|
user.socket.send(serverToClientMessage2.serializeBinary().buffer, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//disconnect webrtc room
|
|
|
|
|
if(!Client.webRtcRoomId){
|
|
|
|
|
/*if(!Client.webRtcRoomId){
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Client.leave(Client.webRtcRoomId);
|
|
|
|
|
delete Client.webRtcRoomId;
|
|
|
|
|
}*/
|
|
|
|
|
//Client.leave(Client.webRtcRoomId);
|
|
|
|
|
//delete Client.webRtcRoomId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public getWorlds(): Map<string, World> {
|
|
|
|
|