Skip to content
20 changes: 10 additions & 10 deletions quickblox.min.js

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions samples/webrtc/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@
};

var CREDENTIALS = {
appId: 92,
authKey: 'wJHdOcQSxXQGWx5',
authSecret: 'BTFsj7Rtt27DAmT'
'prod': {
'appId': 40718,
'authKey': 'AnB-JpA6r4y6RmS',
'authSecret': '3O7Sr5Pg4Qjexwn'
},
'test': {
'appId': 39854,
'authKey': 'JtensAa9y4AM5Yk',
'authSecret': 'AsDFwwwxpr3LN5w'
}
};

var MESSAGES = {
Expand Down
69 changes: 49 additions & 20 deletions samples/webrtc/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,23 @@
}
};

var remoteStreamCounter = 0,
is_firefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
var remoteStreamCounter = 0;

function closeConn(userId) {
app.helpers.notifyIfUserLeaveCall(app.currentSession, userId, 'disconnected', 'Disconnected');
app.currentSession.closeConnection(userId);
}

var ffHack = {
waitingReconnectTimer: null,
waitingReconnectTimeoutCallback: function(userId, cb) {
console.info('Start waitingReconnectTimeoutCallback for Firefox');

clearTimeout(this.waitingReconnectTimer);
cb(userId);
},
isFirefox: navigator.userAgent.toLowerCase().indexOf('firefox') > -1
};

var Router = Backbone.Router.extend({
'routes': {
Expand Down Expand Up @@ -150,13 +165,17 @@
/**
* INIT
*/
var CREDS = app.helpers.getQueryVar('creds') === 'test' ? CONFIG.CREDENTIALS.test : CONFIG.CREDENTIALS.prod;

QB.init(
CONFIG.CREDENTIALS.appId,
CONFIG.CREDENTIALS.authKey,
CONFIG.CREDENTIALS.authSecret,
CREDS.appId,
CREDS.authKey,
CREDS.authSecret,
CONFIG.APP_CONFIG
);

var statesPeerConn = _.invert(QB.webrtc.PeerConnectionState);

app.router = new Router();
Backbone.history.start();

Expand All @@ -180,7 +199,7 @@
app.caller = user;

QB.chat.connect({
jid: QB.chat.helpers.getUserJid( app.caller.id, CONFIG.CREDENTIALS.appId ),
jid: QB.chat.helpers.getUserJid( app.caller.id, CREDS.appId ),
password: 'webAppPass'
}, function(err, res) {
if(err) {
Expand Down Expand Up @@ -550,7 +569,7 @@
console.log('onDisconnectedListener.');
};

QB.webrtc.onCallStatsReport = function onCallStatsReport(session, userId, stats) {
QB.webrtc.onCallStatsReport = function onCallStatsReport(session, userId, stats, error) {
console.group('onCallStatsReport');
console.log('userId: ', userId);
console.log('session: ', session);
Expand All @@ -561,21 +580,29 @@
* Hack for Firefox
* (https://bugzilla.mozilla.org/show_bug.cgi?id=852665)
*/
if(is_firefox) {
var inboundrtp = _.findWhere(stats, {'type': 'inboundrtp'});
if(ffHack.isFirefox) {
var inboundrtp = _.findWhere(stats, {'type': 'inboundrtp'}),
webrtcConf = CONFIG.APP_CONFIG.webrtc,
timeout = (webrtcConf.disconnectTimeInterval - webrtcConf.statsReportTimeInterval) * 1000;

if(!app.helpers.isBytesReceivedChanges(userId, inboundrtp)) {
console.warn('This is Firefox and user ' + userId + ' has lost his connection.');

/**
* 2 - This is how many stats
* we can get without inboundrtp
* before close connection
*/
if(app.network[userId].count >= 2 && !_.isEmpty(app.currentSession)) {
app.currentSession.closeConnection(userId);
app.helpers.notifyIfUserLeaveCall(session, userId, 'disconnected', 'Disconnected');
app.helpers.toggleRemoteVideoView(userId, 'hide');
$('.j-callee_status_' + userId).text('disconnected');

if(!_.isEmpty(app.currentSession) && !ffHack.waitingReconnectTimer) {
ffHack.waitingReconnectTimer = setTimeout(ffHack.waitingReconnectTimeoutCallback, timeout, userId, closeConn);
}
} else {
if(ffHack.waitingReconnectTimer) {
clearTimeout(ffHack.waitingReconnectTimer);
ffHack.waitingReconnectTimer = null;
console.info('clearTimeout(ffHack.waitingReconnectTimer)');
}

app.helpers.toggleRemoteVideoView(userId, 'show');
$('.j-callee_status_' + userId).text('connected');
}
}
};
Expand All @@ -602,6 +629,8 @@
'name': app.caller.full_name
}
});
} else {
app.helpers.notifyIfUserLeaveCall(session, session.opponentsIDs[0], 'closed');
}
};

Expand Down Expand Up @@ -754,9 +783,9 @@

QB.webrtc.onSessionConnectionStateChangedListener = function onSessionConnectionStateChangedListener(session, userId, connectionState) {
console.group('onSessionConnectionStateChangedListener.');
console.log('UserID: ', userId);
console.log('Session: ', session);
console.log('Сonnection state: ', connectionState);
console.log('UserID:', userId);
console.log('Session:', session);
console.log('Сonnection state:', connectionState, statesPeerConn[connectionState]);
console.groupEnd();

var connectionStateName = _.invert(QB.webrtc.SessionConnectionState)[connectionState],
Expand Down
31 changes: 25 additions & 6 deletions samples/webrtc/js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,41 @@
};
app.network = {};


/* [getQueryVar get value of key from search string of url]
* @param {[string]} q [name of query]
* @return {[string]} [value of query]
*/
app.helpers.getQueryVar = function(q){
var query = window.location.search.substring(1),
vars = query.split("&"),
answ = false;

vars.forEach(function(el, i){
var pair = el.split('=');

if(pair[0] === q) {
answ = pair[1];
}
});

return answ;
};

app.helpers.isBytesReceivedChanges = function(userId, inboundrtp) {
var res = true,
inbBytesRec = inboundrtp ? inboundrtp.bytesReceived : 0;

if(app.network[userId] || !inboundrtp) {
if(!app.network[userId]) {
app.network[userId] = {
'bytesReceived': inbBytesRec,
'count': 0
'bytesReceived': inbBytesRec
};
} else {
if(app.network[userId].bytesReceived === inbBytesRec) {
if(app.network[userId].bytesReceived >= inbBytesRec) {
res = false;
} else {
app.network[userId] = {
'bytesReceived': inbBytesRec,
'count': ++app.network[userId].count
'bytesReceived': inbBytesRec
};
}
}
Expand Down
74 changes: 40 additions & 34 deletions src/modules/webrtc/qbRTCPeerConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,11 @@ RTCPeerConnection.prototype._getStatsWrap = function() {
var _statsReportCallback = function() {
_getStats(self, selector,
function (results) {
self.delegate._onCallStatsReport(self.userID, results);
self.delegate._onCallStatsReport(self.userID, results, null);
},
function errorLog(err) {
Helpers.traceError('_getStats error. ' + err.name + ': ' + err.message);
Helpers.traceError('_getStats error. ' + err.name + ': ' + err.message);
self.delegate._onCallStatsReport(self.userID, null, err);
}
);
};
Expand Down Expand Up @@ -336,37 +337,42 @@ RTCPeerConnection.prototype._startDialingTimer = function(extension, withOnNotAn
/**
* PRIVATE
*/
function _getStats(peer, selector, successCallback, errorCallback) {
/**
* http://stackoverflow.com/questions/25069419/webrtc-getstat-api-set-up
*/
if (navigator.mozGetUserMedia) {
peer.getStats(selector,
function (res) {
var items = [];
res.forEach(function (result) {
items.push(result);
});
successCallback(items);
},
errorCallback
);
} else {
peer.getStats(function (res) {
var items = [];
res.result().forEach(function (result) {
var item = {};
result.names().forEach(function (name) {
item[name] = result.stat(name);
});
item.id = result.id;
item.type = result.type;
item.timestamp = result.timestamp;
items.push(item);
});
successCallback(items);
});
}
}
function _getStats(peer, selector, successCallback, errorCallback) {
/**
* http://stackoverflow.com/questions/25069419/webrtc-getstat-api-set-up
*/
if (navigator.mozGetUserMedia) {
peer.getStats(selector,
function (res) {
var items = [];

res.forEach(function (result) {
items.push(result);
});

successCallback(items);
},
errorCallback
);
} else {
peer.getStats(function (res) {
var items = [];

res.result().forEach(function (result) {
var item = {};

result.names().forEach(function (name) {
item[name] = result.stat(name);
});

item.id = result.id;
item.type = result.type;
item.timestamp = result.timestamp;
items.push(item);
});
successCallback(items);
});
}
}

module.exports = RTCPeerConnection;
37 changes: 25 additions & 12 deletions src/modules/webrtc/qbWebRTCSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* - onRemoteStreamListener(session, userID, stream)
* - onSessionConnectionStateChangedListener(session, userID, connectionState)
* - onSessionCloseListener(session)
* - onCallStatsReport(session, userId, stats)
* - onCallStatsReport(session, userId, stats, error)
*/

var config = require('../../qbConfig');
Expand Down Expand Up @@ -365,19 +365,24 @@ WebRTCSession.prototype.stop = function(extension) {

/**
* [function close connection with user]
* @param {[type]} userId [id of user]
* @param {[number]} userId [id of user]
*/
WebRTCSession.prototype.closeConnection = function(userId) {
var self = this,
peer = this.peerConnections[userId];
var self = this,
peer = this.peerConnections[userId];

if(peer) {
peer.release();
if(!peer) {
Helpers.traceWarn('Not found connection with user (' + userId + ')');
return false;
}

self._closeSessionIfAllConnectionsClosed();
} else {
Helpers.traceWarn('Not found connection with user (' + userId + ')');
}
try {
peer.release();
} catch (e) {
Helpers.traceError(e);
} finally {
self._closeSessionIfAllConnectionsClosed();
}
};


Expand Down Expand Up @@ -615,9 +620,17 @@ WebRTCSession.prototype._onRemoteStreamListener = function(userID, stream) {
}
};

WebRTCSession.prototype._onCallStatsReport = function(userId, stats) {
/**
* [_onCallStatsReport return statistics about the peer]
* @param {number} userId [id of user (callee)]
* @param {array} stats [array of statistics]
*
* Fire onCallStatsReport callbacks with parameters(userId, stats, error).
* If stats will be invalid callback return null and error
*/
WebRTCSession.prototype._onCallStatsReport = function(userId, stats, error) {
if (typeof this.onCallStatsReport === 'function'){
Utils.safeCallbackCall(this.onCallStatsReport, this, userId, stats);
Utils.safeCallbackCall(this.onCallStatsReport, this, userId, stats, error);
}
};

Expand Down