Merge branch 'feature-socketio' into develop
commit
10c3427355
|
|
@ -1,9 +1,9 @@
|
|||
import protooClient from 'protoo-client';
|
||||
import io from 'socket.io-client';
|
||||
import * as mediasoupClient from 'mediasoup-client';
|
||||
import Logger from './Logger';
|
||||
import hark from 'hark';
|
||||
import ScreenShare from './ScreenShare';
|
||||
import { getProtooUrl } from './urlFactory';
|
||||
import { getSignalingUrl } from './urlFactory';
|
||||
import * as cookiesManager from './cookiesManager';
|
||||
import * as requestActions from './redux/requestActions';
|
||||
import * as stateActions from './redux/stateActions';
|
||||
|
|
@ -37,8 +37,7 @@ export default class RoomClient
|
|||
'constructor() [roomId:"%s", peerName:"%s", displayName:"%s", device:%s]',
|
||||
roomId, peerName, displayName, device.flag);
|
||||
|
||||
const protooUrl = getProtooUrl(peerName, roomId);
|
||||
const protooTransport = new protooClient.WebSocketTransport(protooUrl);
|
||||
const signalingUrl = getSignalingUrl(peerName, roomId);
|
||||
|
||||
// window element to external login site
|
||||
this._loginWindow;
|
||||
|
|
@ -64,8 +63,8 @@ export default class RoomClient
|
|||
// My peer name.
|
||||
this._peerName = peerName;
|
||||
|
||||
// protoo-client Peer instance.
|
||||
this._protoo = new protooClient.Peer(protooTransport);
|
||||
// Socket.io peer connection
|
||||
this._signalingSocket = io(signalingUrl);
|
||||
|
||||
// mediasoup-client Room instance.
|
||||
this._room = new mediasoupClient.Room(ROOM_OPTIONS);
|
||||
|
|
@ -120,9 +119,9 @@ export default class RoomClient
|
|||
// Leave the mediasoup Room.
|
||||
this._room.leave();
|
||||
|
||||
// Close protoo Peer (wait a bit so mediasoup-client can send
|
||||
// Close signaling Peer (wait a bit so mediasoup-client can send
|
||||
// the 'leaveRoom' notification).
|
||||
setTimeout(() => this._protoo.close(), 250);
|
||||
setTimeout(() => this._signalingSocket.close(), 250);
|
||||
|
||||
this._dispatch(stateActions.setRoomState('closed'));
|
||||
}
|
||||
|
|
@ -144,6 +143,57 @@ export default class RoomClient
|
|||
this._loginWindow.close();
|
||||
}
|
||||
|
||||
timeoutCallback(callback)
|
||||
{
|
||||
let called = false;
|
||||
|
||||
const interval = setTimeout(
|
||||
() =>
|
||||
{
|
||||
if (called)
|
||||
return;
|
||||
called = true;
|
||||
callback(new Error('Callback timeout'));
|
||||
},
|
||||
5000
|
||||
);
|
||||
|
||||
return (...args) =>
|
||||
{
|
||||
if (called)
|
||||
return;
|
||||
called = true;
|
||||
clearTimeout(interval);
|
||||
|
||||
callback(...args);
|
||||
};
|
||||
}
|
||||
|
||||
sendRequest(method, data)
|
||||
{
|
||||
return new Promise((resolve, reject) =>
|
||||
{
|
||||
if (!this._signalingSocket)
|
||||
{
|
||||
reject('No socket connection.');
|
||||
}
|
||||
else
|
||||
{
|
||||
this._signalingSocket.emit(method, data, this.timeoutCallback((err, response) =>
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
reject(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
resolve(response);
|
||||
}
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
changeDisplayName(displayName)
|
||||
{
|
||||
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
||||
|
|
@ -151,7 +201,7 @@ export default class RoomClient
|
|||
// Store in cookie.
|
||||
cookiesManager.setUser({ displayName });
|
||||
|
||||
return this._protoo.send('change-display-name', { displayName })
|
||||
return this.sendRequest('change-display-name', { displayName })
|
||||
.then(() =>
|
||||
{
|
||||
this._dispatch(
|
||||
|
|
@ -182,7 +232,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('changeProfilePicture() [picture: "%s"]', picture);
|
||||
|
||||
this._protoo.send('change-profile-picture', { picture }).catch((error) =>
|
||||
return this.sendRequest('change-profile-picture', { picture }).catch((error) =>
|
||||
{
|
||||
logger.error('shareProfilePicure() | failed: %o', error);
|
||||
});
|
||||
|
|
@ -192,7 +242,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('sendChatMessage() [chatMessage:"%s"]', chatMessage);
|
||||
|
||||
return this._protoo.send('chat-message', { chatMessage })
|
||||
return this.sendRequest('chat-message', { chatMessage })
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('sendChatMessage() | failed: %o', error);
|
||||
|
|
@ -209,7 +259,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('sendFile() [file: %o]', file);
|
||||
|
||||
return this._protoo.send('send-file', { file })
|
||||
return this.sendRequest('send-file', { file })
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('sendFile() | failed: %o', error);
|
||||
|
|
@ -225,7 +275,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('getChatHistory()');
|
||||
|
||||
return this._protoo.send('chat-history', {})
|
||||
return this.sendRequest('chat-history', {})
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('getChatHistory() | failed: %o', error);
|
||||
|
|
@ -242,7 +292,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('getFileHistory()');
|
||||
|
||||
return this._protoo.send('file-history', {})
|
||||
return this.sendRequest('file-history', {})
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('getFileHistory() | failed: %o', error);
|
||||
|
|
@ -940,7 +990,7 @@ export default class RoomClient
|
|||
this._dispatch(
|
||||
stateActions.setMyRaiseHandStateInProgress(true));
|
||||
|
||||
return this._protoo.send('raisehand-message', { raiseHandState: state })
|
||||
return this.sendRequest('raisehand-message', { raiseHandState: state })
|
||||
.then(() =>
|
||||
{
|
||||
this._dispatch(
|
||||
|
|
@ -997,16 +1047,16 @@ export default class RoomClient
|
|||
{
|
||||
this._dispatch(stateActions.setRoomState('connecting'));
|
||||
|
||||
this._protoo.on('open', () =>
|
||||
this._signalingSocket.on('connect', () =>
|
||||
{
|
||||
logger.debug('protoo Peer "open" event');
|
||||
logger.debug('signaling Peer "connect" event');
|
||||
|
||||
this._joinRoom({ displayName, device });
|
||||
});
|
||||
|
||||
this._protoo.on('disconnected', () =>
|
||||
this._signalingSocket.on('disconnect', () =>
|
||||
{
|
||||
logger.warn('protoo Peer "disconnected" event');
|
||||
logger.warn('signaling Peer "disconnect" event');
|
||||
|
||||
this._dispatch(requestActions.notify(
|
||||
{
|
||||
|
|
@ -1015,59 +1065,41 @@ export default class RoomClient
|
|||
}));
|
||||
|
||||
// Leave Room.
|
||||
try { this._room.remoteClose({ cause: 'protoo disconnected' }); }
|
||||
try { this._room.remoteClose({ cause: 'signaling disconnected' }); }
|
||||
catch (error) {}
|
||||
|
||||
this._dispatch(stateActions.setRoomState('connecting'));
|
||||
});
|
||||
|
||||
this._protoo.on('close', () =>
|
||||
this._signalingSocket.on('close', () =>
|
||||
{
|
||||
if (this._closed)
|
||||
return;
|
||||
|
||||
logger.warn('protoo Peer "close" event');
|
||||
logger.warn('signaling Peer "close" event');
|
||||
|
||||
this.close();
|
||||
});
|
||||
|
||||
this._protoo.on('request', (request, accept, reject) =>
|
||||
this._signalingSocket.on('mediasoup-notification', (data) =>
|
||||
{
|
||||
logger.debug(
|
||||
'_handleProtooRequest() [method:%s, data:%o]',
|
||||
request.method, request.data);
|
||||
|
||||
switch (request.method)
|
||||
{
|
||||
case 'mediasoup-notification':
|
||||
{
|
||||
accept();
|
||||
|
||||
const notification = request.data;
|
||||
const notification = data;
|
||||
|
||||
this._room.receiveNotification(notification);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'active-speaker':
|
||||
this._signalingSocket.on('active-speaker', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
const { peerName } = request.data;
|
||||
const { peerName } = data;
|
||||
|
||||
this._dispatch(
|
||||
stateActions.setRoomActiveSpeaker(peerName));
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'display-name-changed':
|
||||
this._signalingSocket.on('display-name-changed', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
const { peerName, displayName, oldDisplayName } = request.data;
|
||||
const { peerName, displayName, oldDisplayName } = data;
|
||||
|
||||
// NOTE: Hack, we shouldn't do this, but this is just a demo.
|
||||
const peer = this._room.getPeerByName(peerName);
|
||||
|
|
@ -1076,7 +1108,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.error('peer not found');
|
||||
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
peer.appData.displayName = displayName;
|
||||
|
|
@ -1088,75 +1120,58 @@ export default class RoomClient
|
|||
{
|
||||
text : `${oldDisplayName} is now ${displayName}`
|
||||
}));
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'profile-picture-changed':
|
||||
this._signalingSocket.on('profile-picture-changed', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
const { peerName, picture } = request.data;
|
||||
const { peerName, picture } = data;
|
||||
|
||||
this._dispatch(stateActions.setPeerPicture(peerName, picture));
|
||||
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// This means: server wants to change MY user information
|
||||
case 'auth':
|
||||
this._signalingSocket.on('auth', (data) =>
|
||||
{
|
||||
logger.debug('got auth event from server', request.data);
|
||||
accept();
|
||||
logger.debug('got auth event from server', data);
|
||||
|
||||
this.changeDisplayName(request.data.name);
|
||||
this.changeDisplayName(data.name);
|
||||
|
||||
this.changeProfilePicture(request.data.picture);
|
||||
this._dispatch(stateActions.setPicture(request.data.picture));
|
||||
this.changeProfilePicture(data.picture);
|
||||
this._dispatch(stateActions.setPicture(data.picture));
|
||||
this._dispatch(stateActions.loggedIn());
|
||||
|
||||
this._dispatch(requestActions.notify(
|
||||
{
|
||||
text : `Authenticated successfully: ${request.data}`
|
||||
text : `Authenticated successfully: ${data}`
|
||||
}
|
||||
));
|
||||
|
||||
this.closeLoginWindow();
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'raisehand-message':
|
||||
this._signalingSocket.on('raisehand-message', (data) =>
|
||||
{
|
||||
accept();
|
||||
const { peerName, raiseHandState } = request.data;
|
||||
const { peerName, raiseHandState } = data;
|
||||
|
||||
logger.debug('Got raiseHandState from "%s"', peerName);
|
||||
|
||||
this._dispatch(
|
||||
stateActions.setPeerRaiseHandState(peerName, raiseHandState));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
case 'chat-message-receive':
|
||||
this._signalingSocket.on('chat-message-receive', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
const { peerName, chatMessage } = request.data;
|
||||
const { peerName, chatMessage } = data;
|
||||
|
||||
logger.debug('Got chat from "%s"', peerName);
|
||||
|
||||
this._dispatch(
|
||||
stateActions.addResponseMessage({ ...chatMessage, peerName }));
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'chat-history-receive':
|
||||
this._signalingSocket.on('chat-history-receive', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
const { chatHistory } = request.data;
|
||||
const { chatHistory } = data;
|
||||
|
||||
if (chatHistory.length > 0)
|
||||
{
|
||||
|
|
@ -1164,30 +1179,22 @@ export default class RoomClient
|
|||
this._dispatch(
|
||||
stateActions.addChatHistory(chatHistory));
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'file-receive':
|
||||
this._signalingSocket.on('file-receive', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
const payload = request.data.file;
|
||||
const payload = data.file;
|
||||
|
||||
this._dispatch(stateActions.addFile(payload));
|
||||
|
||||
this._dispatch(requestActions.notify({
|
||||
text : `${payload.name} shared a file`
|
||||
}));
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'file-history-receive':
|
||||
this._signalingSocket.on('file-history-receive', (data) =>
|
||||
{
|
||||
accept();
|
||||
|
||||
const files = request.data.fileHistory;
|
||||
const files = data.fileHistory;
|
||||
|
||||
if (files.length > 0)
|
||||
{
|
||||
|
|
@ -1195,17 +1202,6 @@ export default class RoomClient
|
|||
|
||||
this._dispatch(stateActions.addFileHistory(files));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
logger.error('unknown protoo method "%s"', request.method);
|
||||
|
||||
reject(404, 'unknown method');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1213,7 +1209,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('_joinRoom()');
|
||||
|
||||
// NOTE: We allow rejoining (room.join()) the same mediasoup Room when Protoo
|
||||
// NOTE: We allow rejoining (room.join()) the same mediasoup Room when
|
||||
// WebSocket re-connects, so we must clean existing event listeners. Otherwise
|
||||
// they will be called twice after the reconnection.
|
||||
this._room.removeAllListeners();
|
||||
|
|
@ -1235,7 +1231,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'sending mediasoup request [method:%s]:%o', request.method, request);
|
||||
|
||||
this._protoo.send('mediasoup-request', request)
|
||||
this.sendRequest('mediasoup-request', request)
|
||||
.then(callback)
|
||||
.catch(errback);
|
||||
});
|
||||
|
|
@ -1246,7 +1242,7 @@ export default class RoomClient
|
|||
'sending mediasoup notification [method:%s]:%o',
|
||||
notification.method, notification);
|
||||
|
||||
this._protoo.send('mediasoup-notification', notification)
|
||||
this.sendRequest('mediasoup-notification', notification)
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.warn('could not send mediasoup notification:%o', error);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export function getProtooUrl(peerName, roomId)
|
||||
export function getSignalingUrl(peerName, roomId)
|
||||
{
|
||||
const hostname = window.location.hostname;
|
||||
const port = window.location.port;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -21,7 +21,6 @@
|
|||
"marked": "^0.4.0",
|
||||
"mediasoup-client": "^2.1.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"protoo-client": "^3.0.0",
|
||||
"random-string": "^0.2.0",
|
||||
"react": "^16.4.2",
|
||||
"react-copy-to-clipboard": "^5.0.1",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const protooServer = require('protoo-server');
|
||||
const WebTorrent = require('webtorrent-hybrid');
|
||||
const Logger = require('./Logger');
|
||||
const config = require('../config');
|
||||
|
|
@ -39,11 +38,10 @@ class Room extends EventEmitter
|
|||
|
||||
this._fileHistory = [];
|
||||
|
||||
this._signalingPeers = new Map();
|
||||
|
||||
try
|
||||
{
|
||||
// Protoo Room instance.
|
||||
this._protooRoom = new protooServer.Room();
|
||||
|
||||
// mediasoup Room instance.
|
||||
this._mediaRoom = mediaServer.Room(config.mediasoup.mediaCodecs);
|
||||
}
|
||||
|
|
@ -75,9 +73,14 @@ class Room extends EventEmitter
|
|||
|
||||
this._closed = true;
|
||||
|
||||
// Close the protoo Room.
|
||||
if (this._protooRoom)
|
||||
this._protooRoom.close();
|
||||
// Close the signalingPeers
|
||||
if (this._signalingPeers)
|
||||
for (let peer of this._signalingPeers)
|
||||
{
|
||||
peer.socket.disconnect();
|
||||
};
|
||||
|
||||
this._signalingPeers.clear();
|
||||
|
||||
// Close the mediasoup Room.
|
||||
if (this._mediaRoom)
|
||||
|
|
@ -93,31 +96,32 @@ class Room extends EventEmitter
|
|||
return;
|
||||
|
||||
logger.info(
|
||||
'logStatus() [room id:"%s", protoo peers:%s, mediasoup peers:%s]',
|
||||
'logStatus() [room id:"%s", peers:%s, mediasoup peers:%s]',
|
||||
this._roomId,
|
||||
this._protooRoom.peers.length,
|
||||
this._signalingPeers.length,
|
||||
this._mediaRoom.peers.length);
|
||||
}
|
||||
|
||||
handleConnection(peerName, transport)
|
||||
handleConnection(peerName, socket)
|
||||
{
|
||||
logger.info('handleConnection() [peerName:"%s"]', peerName);
|
||||
|
||||
if (this._protooRoom.hasPeer(peerName))
|
||||
if (this._signalingPeers.has(peerName))
|
||||
{
|
||||
logger.warn(
|
||||
'handleConnection() | there is already a peer with same peerName, ' +
|
||||
'closing the previous one [peerName:"%s"]',
|
||||
peerName);
|
||||
|
||||
const protooPeer = this._protooRoom.getPeer(peerName);
|
||||
const signalingPeer = this._signalingPeers.get(peerName);
|
||||
|
||||
protooPeer.close();
|
||||
signalingPeer.socket.disconnect();
|
||||
this._signalingPeers.delete(peerName);
|
||||
}
|
||||
|
||||
const protooPeer = this._protooRoom.createPeer(peerName, transport);
|
||||
const signalingPeer = { peerName : peerName, socket : socket };
|
||||
|
||||
this._handleProtooPeer(protooPeer);
|
||||
this._handleSignalingPeer(signalingPeer);
|
||||
}
|
||||
|
||||
_handleMediaRoom()
|
||||
|
|
@ -173,8 +177,8 @@ class Room extends EventEmitter
|
|||
}
|
||||
}
|
||||
|
||||
// Spread to others via protoo.
|
||||
this._protooRoom.spread(
|
||||
// Spread to room
|
||||
this.emit(
|
||||
'active-speaker',
|
||||
{
|
||||
peerName : activePeer ? activePeer.name : null
|
||||
|
|
@ -182,110 +186,99 @@ class Room extends EventEmitter
|
|||
});
|
||||
}
|
||||
|
||||
_handleProtooPeer(protooPeer)
|
||||
_handleSignalingPeer(signalingPeer)
|
||||
{
|
||||
logger.debug('_handleProtooPeer() [peer:"%s"]', protooPeer.id);
|
||||
logger.debug('_handleSignalingPeer() [peer:"%s"]', signalingPeer.id);
|
||||
|
||||
protooPeer.on('request', (request, accept, reject) =>
|
||||
signalingPeer.socket.on('mediasoup-request', (request, cb) =>
|
||||
{
|
||||
logger.debug(
|
||||
'protoo "request" event [method:%s, peer:"%s"]',
|
||||
request.method, protooPeer.id);
|
||||
|
||||
switch (request.method)
|
||||
{
|
||||
case 'mediasoup-request':
|
||||
{
|
||||
const mediasoupRequest = request.data;
|
||||
const mediasoupRequest = request;
|
||||
|
||||
this._handleMediasoupClientRequest(
|
||||
protooPeer, mediasoupRequest, accept, reject);
|
||||
signalingPeer, mediasoupRequest, cb);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'mediasoup-notification':
|
||||
signalingPeer.socket.on('mediasoup-notification', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
const mediasoupNotification = request.data;
|
||||
const mediasoupNotification = request;
|
||||
|
||||
this._handleMediasoupClientNotification(
|
||||
protooPeer, mediasoupNotification);
|
||||
signalingPeer, mediasoupNotification);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'change-display-name':
|
||||
signalingPeer.socket.on('change-display-name', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
const { displayName } = request.data;
|
||||
const { mediaPeer } = protooPeer.data;
|
||||
const { displayName } = request;
|
||||
const mediaPeer = this._mediaRoom.getPeerByName(peerName);
|
||||
const oldDisplayName = mediaPeer.appData.displayName;
|
||||
|
||||
mediaPeer.appData.displayName = displayName;
|
||||
|
||||
// Spread to others via protoo.
|
||||
this._protooRoom.spread(
|
||||
signalingPeer.socket.broadcast.to(this._roomId).emit(
|
||||
'display-name-changed',
|
||||
{
|
||||
peerName : protooPeer.id,
|
||||
peerName : signalingPeer.peerName,
|
||||
displayName : displayName,
|
||||
oldDisplayName : oldDisplayName
|
||||
},
|
||||
[ protooPeer ]);
|
||||
|
||||
break;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
case 'change-profile-picture':
|
||||
signalingPeer.socket.on('change-profile-picture', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
this._protooRoom.spread('profile-picture-changed', {
|
||||
peerName : protooPeer.id,
|
||||
picture : request.data.picture
|
||||
}, [ protooPeer ]);
|
||||
|
||||
break;
|
||||
signalingPeer.socket.broadcast.to(this._roomId).emit(
|
||||
'profile-picture-changed',
|
||||
{
|
||||
peerName : signalingPeer.peerName,
|
||||
picture : request.picture
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
case 'chat-message':
|
||||
signalingPeer.socket.on('chat-message', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
const { chatMessage } = request.data;
|
||||
const { chatMessage } = request;
|
||||
|
||||
this._chatHistory.push(chatMessage);
|
||||
|
||||
// Spread to others via protoo.
|
||||
this._protooRoom.spread(
|
||||
// Spread to others
|
||||
signalingPeer.socket.broadcast.to(this._roomId).emit(
|
||||
'chat-message-receive',
|
||||
{
|
||||
peerName : protooPeer.id,
|
||||
peerName : signalingPeer.peerName,
|
||||
chatMessage : chatMessage
|
||||
},
|
||||
[ protooPeer ]);
|
||||
|
||||
break;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
case 'chat-history':
|
||||
signalingPeer.socket.on('chat-history', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
protooPeer.send(
|
||||
// Return to socket
|
||||
signalingPeer.socket.emit(
|
||||
'chat-history-receive',
|
||||
{ chatHistory: this._chatHistory }
|
||||
);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'send-file':
|
||||
signalingPeer.socket.on('send-file', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
const fileData = request.data.file;
|
||||
|
||||
|
|
@ -296,58 +289,53 @@ class Room extends EventEmitter
|
|||
torrentClient.add(fileData.file.magnet);
|
||||
}
|
||||
|
||||
this._protooRoom.spread('file-receive', {
|
||||
file : fileData
|
||||
}, [ protooPeer ]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'file-history':
|
||||
// Spread to others
|
||||
signalingPeer.socket.broadcast.to(this._roomId).emit(
|
||||
'file-receive',
|
||||
{
|
||||
accept();
|
||||
|
||||
protooPeer.send('file-history-receive', {
|
||||
fileHistory : this._fileHistory
|
||||
file : fileData
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'raisehand-message':
|
||||
signalingPeer.socket.on('file-history', (request, cb) =>
|
||||
{
|
||||
accept();
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
// Return to socket
|
||||
signalingPeer.socket.emit(
|
||||
'file-history-receive',
|
||||
{
|
||||
fileHistory : this._fileHistory
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
signalingPeer.socket.on('raisehand-message', (request, cb) =>
|
||||
{
|
||||
// Return no error
|
||||
cb(null);
|
||||
|
||||
const { raiseHandState } = request.data;
|
||||
const { mediaPeer } = protooPeer.data;
|
||||
const { mediaPeer } = signalingPeer;
|
||||
|
||||
mediaPeer.appData.raiseHandState = request.data.raiseHandState;
|
||||
// Spread to others via protoo.
|
||||
this._protooRoom.spread(
|
||||
// Spread to others
|
||||
signalingPeer.socket.broadcast.to(this._roomId).emit(
|
||||
'raisehand-message',
|
||||
{
|
||||
peerName : protooPeer.id,
|
||||
peerName : signalingPeer.peerName,
|
||||
raiseHandState : raiseHandState
|
||||
},
|
||||
[ protooPeer ]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
logger.error('unknown request.method "%s"', request.method);
|
||||
|
||||
reject(400, `unknown request.method "${request.method}"`);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
protooPeer.on('close', () =>
|
||||
signalingPeer.socket.on('disconnect', () =>
|
||||
{
|
||||
logger.debug('protoo Peer "close" event [peer:"%s"]', protooPeer.id);
|
||||
logger.debug('Peer "close" event [peer:"%s"]', signalingPeer.peerName);
|
||||
|
||||
const { mediaPeer } = protooPeer.data;
|
||||
const mediaPeer = this._mediaRoom.getPeerByName(signalingPeer.peerName);
|
||||
|
||||
if (mediaPeer && !mediaPeer.closed)
|
||||
mediaPeer.close();
|
||||
|
|
@ -371,12 +359,11 @@ class Room extends EventEmitter
|
|||
});
|
||||
}
|
||||
|
||||
_handleMediaPeer(protooPeer, mediaPeer)
|
||||
_handleMediaPeer(signalingPeer, mediaPeer)
|
||||
{
|
||||
mediaPeer.on('notify', (notification) =>
|
||||
{
|
||||
protooPeer.send('mediasoup-notification', notification)
|
||||
.catch(() => {});
|
||||
signalingPeer.socket.emit('mediasoup-notification', notification);
|
||||
});
|
||||
|
||||
mediaPeer.on('newtransport', (transport) =>
|
||||
|
|
@ -424,12 +411,11 @@ class Room extends EventEmitter
|
|||
// Notify about the existing active speaker.
|
||||
if (this._currentActiveSpeaker)
|
||||
{
|
||||
protooPeer.send(
|
||||
signalingPeer.socket.emit(
|
||||
'active-speaker',
|
||||
{
|
||||
peerName : this._currentActiveSpeaker.name
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -495,19 +481,19 @@ class Room extends EventEmitter
|
|||
consumer.setPreferredProfile('low');
|
||||
}
|
||||
|
||||
_handleMediasoupClientRequest(protooPeer, request, accept, reject)
|
||||
_handleMediasoupClientRequest(signalingPeer, request, cb)
|
||||
{
|
||||
logger.debug(
|
||||
'mediasoup-client request [method:%s, peer:"%s"]',
|
||||
request.method, protooPeer.id);
|
||||
request.method, signalingPeer.peerName);
|
||||
|
||||
switch (request.method)
|
||||
{
|
||||
case 'queryRoom':
|
||||
{
|
||||
this._mediaRoom.receiveRequest(request)
|
||||
.then((response) => accept(response))
|
||||
.catch((error) => reject(500, error.toString()));
|
||||
.then((response) => cb(null, response))
|
||||
.catch((error) => cb(error.toString()));
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -517,15 +503,15 @@ class Room extends EventEmitter
|
|||
// TODO: Handle appData. Yes?
|
||||
const { peerName } = request;
|
||||
|
||||
if (peerName !== protooPeer.id)
|
||||
if (peerName !== signalingPeer.peerName)
|
||||
{
|
||||
reject(403, 'that is not your corresponding mediasoup Peer name');
|
||||
cb('that is not your corresponding mediasoup Peer name');
|
||||
|
||||
break;
|
||||
}
|
||||
else if (protooPeer.data.mediaPeer)
|
||||
else if (signalingPeer.mediaPeer)
|
||||
{
|
||||
reject(500, 'already have a mediasoup Peer');
|
||||
cb('already have a mediasoup Peer');
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -533,18 +519,18 @@ class Room extends EventEmitter
|
|||
this._mediaRoom.receiveRequest(request)
|
||||
.then((response) =>
|
||||
{
|
||||
accept(response);
|
||||
cb(null, response);
|
||||
|
||||
// Get the newly created mediasoup Peer.
|
||||
const mediaPeer = this._mediaRoom.getPeerByName(peerName);
|
||||
|
||||
protooPeer.data.mediaPeer = mediaPeer;
|
||||
signalingPeer.mediaPeer = mediaPeer;
|
||||
|
||||
this._handleMediaPeer(protooPeer, mediaPeer);
|
||||
this._handleMediaPeer(signalingPeer, mediaPeer);
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
reject(500, error.toString());
|
||||
cb(error.toString());
|
||||
});
|
||||
|
||||
break;
|
||||
|
|
@ -552,7 +538,7 @@ class Room extends EventEmitter
|
|||
|
||||
default:
|
||||
{
|
||||
const { mediaPeer } = protooPeer.data;
|
||||
const { mediaPeer } = signalingPeer;
|
||||
|
||||
if (!mediaPeer)
|
||||
{
|
||||
|
|
@ -560,25 +546,25 @@ class Room extends EventEmitter
|
|||
'cannot handle mediasoup request, no mediasoup Peer [method:"%s"]',
|
||||
request.method);
|
||||
|
||||
reject(400, 'no mediasoup Peer');
|
||||
cb('no mediasoup Peer');
|
||||
}
|
||||
|
||||
mediaPeer.receiveRequest(request)
|
||||
.then((response) => accept(response))
|
||||
.catch((error) => reject(500, error.toString()));
|
||||
.then((response) => cb(null, response))
|
||||
.catch((error) => cb(error.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_handleMediasoupClientNotification(protooPeer, notification)
|
||||
_handleMediasoupClientNotification(signalingPeer, notification)
|
||||
{
|
||||
logger.debug(
|
||||
'mediasoup-client notification [method:%s, peer:"%s"]',
|
||||
notification.method, protooPeer.id);
|
||||
notification.method, signalingPeer.peerName);
|
||||
|
||||
// NOTE: mediasoup-client just sends notifications with target 'peer',
|
||||
// so first of all, get the mediasoup Peer.
|
||||
const { mediaPeer } = protooPeer.data;
|
||||
const { mediaPeer } = signalingPeer;
|
||||
|
||||
if (!mediaPeer)
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -13,8 +13,8 @@
|
|||
"express": "^4.16.3",
|
||||
"mediasoup": "^2.1.0",
|
||||
"passport-dataporten": "^1.3.0",
|
||||
"protoo-server": "^2.0.7",
|
||||
"webtorrent-hybrid": "^1.0.6"
|
||||
"webtorrent-hybrid": "^1.0.6",
|
||||
"socket.io": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^4.0.0",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ const fs = require('fs');
|
|||
const https = require('https');
|
||||
const express = require('express');
|
||||
const url = require('url');
|
||||
const protooServer = require('protoo-server');
|
||||
const Logger = require('./lib/Logger');
|
||||
const Room = require('./lib/Room');
|
||||
const Dataporten = require('passport-dataporten');
|
||||
|
|
@ -98,29 +97,18 @@ httpsServer.listen(config.listeningPort, '0.0.0.0', () =>
|
|||
logger.info('Server running on port: ', config.listeningPort);
|
||||
});
|
||||
|
||||
// Protoo WebSocket server listens to same webserver so everything is available
|
||||
// via same port
|
||||
const webSocketServer = new protooServer.WebSocketServer(httpsServer,
|
||||
{
|
||||
maxReceivedFrameSize : 960000, // 960 KBytes.
|
||||
maxReceivedMessageSize : 960000,
|
||||
fragmentOutgoingMessages : true,
|
||||
fragmentationThreshold : 960000
|
||||
});
|
||||
const io = require('socket.io')(httpsServer);
|
||||
|
||||
// Handle connections from clients.
|
||||
webSocketServer.on('connectionrequest', (info, accept, reject) =>
|
||||
io.on('connection', (socket) =>
|
||||
{
|
||||
// The client indicates the roomId and peerId in the URL query.
|
||||
const u = url.parse(info.request.url, true);
|
||||
const roomId = u.query['roomId'];
|
||||
const peerName = u.query['peerName'];
|
||||
const { roomId, peerName } = socket.handshake.query;
|
||||
|
||||
if (!roomId || !peerName)
|
||||
{
|
||||
logger.warn('connection request without roomId and/or peerName');
|
||||
|
||||
reject(400, 'Connection request without roomId and/or peerName');
|
||||
socket.disconnect(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -145,7 +133,7 @@ webSocketServer.on('connectionrequest', (info, accept, reject) =>
|
|||
{
|
||||
logger.error('error creating a new Room: %s', error);
|
||||
|
||||
reject(error);
|
||||
socket.disconnect(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -157,6 +145,11 @@ webSocketServer.on('connectionrequest', (info, accept, reject) =>
|
|||
|
||||
rooms.set(roomId, room);
|
||||
|
||||
room.on('active-speaker', (message) =>
|
||||
{
|
||||
io.to(roomId).emit('active-speaker', message);
|
||||
});
|
||||
|
||||
room.on('close', () =>
|
||||
{
|
||||
rooms.delete(roomId);
|
||||
|
|
@ -168,7 +161,8 @@ webSocketServer.on('connectionrequest', (info, accept, reject) =>
|
|||
room = rooms.get(roomId);
|
||||
}
|
||||
|
||||
const transport = accept();
|
||||
socket.join(roomId);
|
||||
socket.room = roomId;
|
||||
|
||||
room.handleConnection(peerName, transport);
|
||||
room.handleConnection(peerName, socket);
|
||||
});
|
||||
Loading…
Reference in New Issue