Skip to content

Commit

Permalink
Add a new API to enable Single PC in ErizoClient (#1165)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcague authored Mar 9, 2018
1 parent 552323d commit c574ad3
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 35 deletions.
28 changes: 21 additions & 7 deletions erizo_controller/erizoClient/src/ErizoConnectionManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,35 @@ class ErizoConnectionManager {
this.ErizoConnectionsMap = new Map(); // key: erizoId, value: {connectionId: connection}
}

getOrBuildErizoConnection(specInput, erizoId = undefined) {
getOrBuildErizoConnection(specInput, erizoId = undefined, singlePC = false) {
Logger.debug(`message: getOrBuildErizoConnection, erizoId: ${erizoId}`);
let connection = {};

if (erizoId === undefined) {
// we have no erizoJS id - p2p
return new ErizoConnection(specInput);
}
connection = new ErizoConnection(specInput, erizoId);
if (this.ErizoConnectionsMap.has(erizoId)) {
this.ErizoConnectionsMap.get(erizoId)[connection.sessionId] = connection;
if (singlePC) {
let connectionEntry;
if (this.ErizoConnectionsMap.has(erizoId)) {
connectionEntry = this.ErizoConnectionsMap.get(erizoId);
} else {
connectionEntry = {};
this.ErizoConnectionsMap.set(erizoId, connectionEntry);
}
if (!connectionEntry['single-pc']) {
connectionEntry['single-pc'] = new ErizoConnection(specInput);
}
connection = connectionEntry['single-pc'];
} else {
const connectionEntry = {};
connectionEntry[connection.sessionId] = connection;
this.ErizoConnectionsMap.set(erizoId, connectionEntry);
connection = new ErizoConnection(specInput, erizoId);
if (this.ErizoConnectionsMap.has(erizoId)) {
this.ErizoConnectionsMap.get(erizoId)[connection.sessionId] = connection;
} else {
const connectionEntry = {};
connectionEntry[connection.sessionId] = connection;
this.ErizoConnectionsMap.set(erizoId, connectionEntry);
}
}
return connection;
}
Expand Down
10 changes: 5 additions & 5 deletions erizo_controller/erizoClient/src/Room.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,7 @@ const Room = (altIo, altConnectionHelpers, altConnectionManager, specInput) => {

const createRemoteStreamErizoConnection = (streamInput, erizoId, options) => {
const stream = streamInput;
stream.pc =
that.erizoConnectionManager.getOrBuildErizoConnection(
stream.pc = that.erizoConnectionManager.getOrBuildErizoConnection(
getErizoConnectionOptions(stream, options, true), erizoId);

stream.pc.onaddstream = dispatchStreamSubscribed.bind(null, stream);
Expand All @@ -204,7 +203,7 @@ const Room = (altIo, altConnectionHelpers, altConnectionManager, specInput) => {
const createLocalStreamErizoConnection = (streamInput, erizoId, options) => {
const stream = streamInput;
stream.pc = that.erizoConnectionManager.getOrBuildErizoConnection(
getErizoConnectionOptions(stream, options), erizoId);
getErizoConnectionOptions(stream, options), erizoId, spec.singlePC);

stream.pc.addStream(stream);
stream.pc.oniceconnectionstatechange = (state) => {
Expand Down Expand Up @@ -566,7 +565,7 @@ const Room = (altIo, altConnectionHelpers, altConnectionManager, specInput) => {

// It stablishes a connection to the room.
// Once it is done it throws a RoomEvent("room-connected")
that.connect = () => {
that.connect = (options = {}) => {
const token = Base64.decodeBase64(spec.token);

if (that.state !== DISCONNECTED) {
Expand All @@ -575,7 +574,7 @@ const Room = (altIo, altConnectionHelpers, altConnectionManager, specInput) => {

// 1- Connect to Erizo-Controller
that.state = CONNECTING;
socket.connect(JSON.parse(token), (response) => {
socket.connect(JSON.parse(token), options, (response) => {
let stream;
const streamList = [];
const streams = response.streams || [];
Expand All @@ -584,6 +583,7 @@ const Room = (altIo, altConnectionHelpers, altConnectionManager, specInput) => {
that.p2p = response.p2p;
that.iceServers = response.iceServers;
that.state = CONNECTED;
spec.singlePC = response.singlePC;
spec.defaultVideoBW = response.defaultVideoBW;
spec.maxVideoBW = response.maxVideoBW;

Expand Down
6 changes: 4 additions & 2 deletions erizo_controller/erizoClient/src/Socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const Socket = (newIo) => {
});
};

that.connect = (token, callback = defaultCallback, error = defaultCallback) => {
that.connect = (token, userOptions, callback = defaultCallback, error = defaultCallback) => {
const options = {
reconnection: true,
reconnectionAttempts: 3,
Expand Down Expand Up @@ -139,7 +139,9 @@ const Socket = (newIo) => {
});

// First message with the token
that.sendMessage('token', token, (response) => {
const message = userOptions;
message.token = token;
that.sendMessage('token', message, (response) => {
that.state = that.CONNECTED;
that.id = response.clientId;
callback(response);
Expand Down
15 changes: 12 additions & 3 deletions erizo_controller/erizoController/erizoController.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ global.config.erizoController.report.session_events =
global.config.erizoController.recording_path =
global.config.erizoController.recording_path || undefined;
global.config.erizoController.exitOnNuveCheckFail = global.config.erizoController.exitOnNuveCheckFail || false;
global.config.erizoController.allowSinglePC = global.config.erizoController.allowSinglePC || '';
// jshint ignore:end
global.config.erizoController.roles = global.config.erizoController.roles ||
{'presenter': {'publish': true, 'subscribe': true, 'record': true},
Expand Down Expand Up @@ -288,17 +289,24 @@ var updateMyState = function () {
nuve.setInfo({id: myId, state: myState});
};

var getSinglePCConfig = function(singlePC) {
return !!singlePC && global.config.erizoController.allowSinglePC;
};

var listen = function () {
io.sockets.on('connection', function (socket) {
log.info('message: socket connected, socketId: ' + socket.id);

let channel = new Channel(socket, nuve);

channel.on('connected', (token, callback) => {
channel.on('connected', (token, options, callback) => {
options = options || {};
try {
let room = rooms.getOrCreateRoom(token.room, token.p2p);
let client = room.createClient(channel, token);
log.info('message: client connected, clientId: ' + client.id);
options.singlePC = getSinglePCConfig(options.singlePC);
let client = room.createClient(channel, token, options);
log.info('message: client connected, clientId: ' + client.id +
', singlePC: ' + options.singlePC);
if (!room.p2p && global.config.erizoController.report.session_events) { // jshint ignore:line
var timeStamp = new Date();
amqper.broadcast('event', {room: room.id,
Expand All @@ -315,6 +323,7 @@ var listen = function () {
callback('success', {streams: streamList,
id: room.id,
clientId: client.id,
singlePC: client.singlePC,
p2p: room.p2p,
defaultVideoBW: global.config.erizoController.defaultVideoBW,
maxVideoBW: global.config.erizoController.maxVideoBW,
Expand Down
7 changes: 4 additions & 3 deletions erizo_controller/erizoController/models/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,14 @@ class Channel extends events.EventEmitter {
listenToSocketHandshakeEvents(this);
}

onToken(token, callback) {
log.debug('message: token received');
onToken(options, callback) {
const token = options.token;
log.debug('message: token received, options: ', options);
if (checkSignature(token, NUVE_KEY)) {
this.nuve.deleteToken(token.tokenId).then(tokenDB => {
if (token.host === tokenDB.host) {
this.state = CONNECTED;
this.emit('connected', tokenDB, callback);
this.emit('connected', tokenDB, options, callback);
} else {
log.warn('message: Token has invalid host, clientId: ' + this.id);
callback('error', 'Invalid host');
Expand Down
7 changes: 5 additions & 2 deletions erizo_controller/erizoController/models/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ function listenToSocketEvents(client) {
}

class Client extends events.EventEmitter {
constructor(channel, token, room) {
constructor(channel, token, options, room) {
super();
this.channel = channel;
this.room = room;
this.token = token;
this.id = uuidv4();
this.options = options;
listenToSocketEvents(this);
this.user = {name: token.userName, role: token.role, permissions: {}};
const permissions = global.config.erizoController.roles[token.role] || [];
Expand Down Expand Up @@ -176,8 +177,9 @@ class Client extends events.EventEmitter {
} else if (options.state === 'erizo') {
let st;
options.mediaConfiguration = this.token.mediaConfiguration;
options.singlePC = this.options.singlePC || false;
log.info('message: addPublisher requested, ' +
'streamId: ' + id + ', clientId: ' + this.id + ', ' +
'streamId: ' + id + ', clientId: ' + this.id +
logger.objectToLog(options) + ', ' +
logger.objectToLog(options.attributes));
this.room.controller.addPublisher(this.id, id, options, (signMess) => {
Expand Down Expand Up @@ -293,6 +295,7 @@ class Client extends events.EventEmitter {
'streamId: ' + options.streamId + ', ' +
'clientId: ' + this.id);
options.mediaConfiguration = this.token.mediaConfiguration;
options.singlePC = this.options.singlePC || false;
this.room.controller.addSubscriber(this.id, options.streamId, options, (signMess) => {
if (signMess.type === 'initializing') {
log.info('message: addSubscriber, ' +
Expand Down
4 changes: 2 additions & 2 deletions erizo_controller/erizoController/models/Room.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class Room extends events.EventEmitter {
return this.clients.get(id);
}

createClient(channel, token) {
let client = new Client(channel, token, this);
createClient(channel, token, options) {
let client = new Client(channel, token, options, this);
client.on('disconnect', this.onClientDisconnected.bind(this, client));
this.clients.set(client.id, client);
return client;
Expand Down
8 changes: 4 additions & 4 deletions erizo_controller/erizoJS/erizoJSController.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ exports.ErizoJSController = function (threadPool, ioThreadPool) {
that.publishers = publishers;
that.ioThreadPool = io;

getOrCreateClient = (clientId) => {
getOrCreateClient = (clientId, singlePC = false) => {
log.debug(`getOrCreateClient with id ${clientId}`);
let client = clients.get(clientId);
if(client === undefined) {
client = new Client(clientId, threadPool, ioThreadPool);
client = new Client(clientId, threadPool, ioThreadPool, !!singlePC);
clients.set(clientId, client);
}
return client;
Expand Down Expand Up @@ -145,7 +145,7 @@ exports.ErizoJSController = function (threadPool, ioThreadPool) {
that.addPublisher = function (clientId, streamId, options, callbackRpc) {
let publisher;
log.info('addPublisher, clientId', clientId, 'streamId', streamId);
let client = getOrCreateClient(clientId);
let client = getOrCreateClient(clientId, options.singlePC);

if (publishers[streamId] === undefined) {
options.publicIP = that.publicIP;
Expand Down Expand Up @@ -192,7 +192,7 @@ exports.ErizoJSController = function (threadPool, ioThreadPool) {
return;
}
let subscriber = publisher.getSubscriber(clientId);
const client = getOrCreateClient(clientId);
const client = getOrCreateClient(clientId, options.singlePC);
if (subscriber !== undefined) {
log.warn('message: Duplicated subscription will resubscribe, ' +
'code: ' + WARN_CONFLICT + ', streamId: ' + streamId +
Expand Down
2 changes: 1 addition & 1 deletion erizo_controller/erizoJS/models/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Client {

getOrCreateConnection(options) {
let connection = this.connections.values().next().value;
log.info(`message: getOrCreateConnection for clientId ${this.id}`);
log.info(`message: getOrCreateConnection, clientId: ${this.id}, singlePC: ${this.singlePc}`);
if (!this.singlePc || !connection) {
let id = this._getNewConnectionClientId();
connection = new Connection(id, this.threadPool, this.ioThreadPool, options);
Expand Down
8 changes: 4 additions & 4 deletions erizo_controller/test/erizoController/erizoController.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ describe('Erizo Controller / Erizo Controller', function() {
it('should fail if signature is wrong', function() {
var callback = sinon.stub();

onToken(arbitraryBadToken, callback);
onToken({token: arbitraryBadToken}, callback);

expect(callback.withArgs('error', 'Authentication error').callCount).to.equal(1);
});

it('should call Nuve if signature is ok', function() {
var callback = sinon.stub();

onToken(arbitraryGoodToken, callback);
onToken({token: arbitraryGoodToken}, callback);

expect(amqperMock.callRpc
.withArgs('nuve', 'deleteToken', arbitraryGoodToken.tokenId).callCount).to.equal(1);
Expand All @@ -157,7 +157,7 @@ describe('Erizo Controller / Erizo Controller', function() {

beforeEach(function() {
onTokenCallback = sinon.stub();
onToken(arbitraryGoodToken, onTokenCallback);
onToken({token: arbitraryGoodToken}, onTokenCallback);

callback = amqperMock.callRpc
.withArgs('nuve', 'deleteToken', arbitraryGoodToken.tokenId)
Expand Down Expand Up @@ -207,7 +207,7 @@ describe('Erizo Controller / Erizo Controller', function() {
expect(roomControllerMock.RoomController.callCount).to.equal(1);
expect(mocks.roomControllerInstance.addEventListener.callCount).to.equal(1);
expect(onTokenCallback.withArgs('success').callCount).to.equal(1);
onToken(arbitraryGoodToken, onTokenCallback);
onToken({token: arbitraryGoodToken}, onTokenCallback);
let callback2 = amqperMock.callRpc
.withArgs('nuve', 'deleteToken', arbitraryGoodToken.tokenId)
.args[1][3].callback;
Expand Down
5 changes: 3 additions & 2 deletions extras/basic_example/public/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ window.onload = function () {
recording = false;
var screen = getParameterByName('screen');
var roomName = getParameterByName('room') || 'basicExampleRoom';
var singlePC = getParameterByName('singlePC') || false;
var roomType = getParameterByName('type') || 'erizo';
var mediaConfiguration = getParameterByName('mediaConfiguration') || 'default';
var onlySubscribe = getParameterByName('onlySubscribe');
Expand Down Expand Up @@ -147,15 +148,15 @@ window.onload = function () {
});

if (onlySubscribe) {
room.connect();
room.connect({singlePC: singlePC});
} else {
var div = document.createElement('div');
div.setAttribute('style', 'width: 320px; height: 240px; float:left');
div.setAttribute('id', 'myVideo');
document.getElementById('videoContainer').appendChild(div);

localStream.addEventListener('access-accepted', function () {
room.connect();
room.connect({singlePC: singlePC});
localStream.show('myVideo');
});
localStream.init();
Expand Down
1 change: 1 addition & 0 deletions scripts/licode_default.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ config.erizoController.listen_port = 8080; //default value: 8080
// config.erizoController.networkInterface = 'eth1' // default value: undefined

config.erizoController.exitOnNuveCheckFail = false; // default value: false
config.erizoController.allowSinglePC = false; // default value: false

config.erizoController.warning_n_rooms = 15; // default value: 15
config.erizoController.limit_n_rooms = 20; // default value: 20
Expand Down

0 comments on commit c574ad3

Please sign in to comment.