Skip to content

Commit

Permalink
Revert "Merge pull request webrtc#346 from webrtc/dtlsLoopback"
Browse files Browse the repository at this point in the history
This reverts commit bb8f949, reversing
changes made to 9336635.
  • Loading branch information
KaptenJansson committed Sep 1, 2016
1 parent bb8f949 commit a9b1aff
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 129 deletions.
20 changes: 7 additions & 13 deletions src/app_engine/apprtc.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ def get_room_parameters(request, room_id, client_id, is_initiator):

debug = request.get('debug')
if debug == 'loopback':
# Set dtls to false as DTLS does not work for loopback.
dtls = 'false'
include_loopback_js = '<script src="/js/loopback.js"></script>'
else:
include_loopback_js = ''
Expand Down Expand Up @@ -386,6 +388,8 @@ def add_client_to_room(request, room_id, client_id, is_loopback):
if occupancy == 0:
is_initiator = True
room.add_client(client_id, Client(is_initiator))
if is_loopback:
room.add_client(constants.LOOPBACK_CLIENT_ID, Client(False))
else:
is_initiator = False
other_client = room.get_other_client(client_id)
Expand All @@ -406,7 +410,7 @@ def add_client_to_room(request, room_id, client_id, is_loopback):
else:
retries = retries + 1
return {'error': error, 'is_initiator': is_initiator,
'messages': messages, 'room_state': str(room), 'client_id': client_id}
'messages': messages, 'room_state': str(room)}

def remove_client_from_room(host, room_id, client_id):
key = get_memcache_key_for_room(host, room_id)
Expand Down Expand Up @@ -527,18 +531,8 @@ def write_room_parameters(self, room_id, client_id, messages, is_initiator):
self.write_response('SUCCESS', params, messages)

def post(self, room_id):
client_id = generate_random(8)
is_loopback = self.request.get('debug') == 'loopback'
if is_loopback:
client_id = constants.LOOPBACK_CLIENT_ID
memcache_client = memcache.Client()
room = memcache_client.gets(
get_memcache_key_for_room(self.request.host_url, room_id))
if room is not None:
if room.has_client(client_id):
client_id = constants.LOOPBACK_CLIENT_ID_2
else:
client_id = generate_random(8)

result = add_client_to_room(self.request, room_id, client_id, is_loopback)
if result['error'] is not None:
logging.info('Error adding client to room: ' + result['error'] + \
Expand All @@ -547,7 +541,7 @@ def post(self, room_id):
return

self.write_room_parameters(
room_id, result['client_id'], result['messages'], result['is_initiator'])
room_id, client_id, result['messages'], result['is_initiator'])
logging.info('User ' + client_id + ' joined room ' + room_id)
logging.info('Room ' + room_id + ' has state ' + result['room_state'])

Expand Down
2 changes: 0 additions & 2 deletions src/app_engine/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
ROOM_MEMCACHE_EXPIRATION_SEC = 60 * 60 * 24
MEMCACHE_RETRY_LIMIT = 100

# Client ID's for the loopback peerconnections.
LOOPBACK_CLIENT_ID = 'LOOPBACK_CLIENT_ID'
LOOPBACK_CLIENT_ID_2 = 'LOOPBACK_CLIENT_ID_2'

# TODO: Remove once clients support ICE_SERVER.
TURN_BASE_URL = 'https://computeengineondemand.appspot.com'
Expand Down
3 changes: 0 additions & 3 deletions src/web_app/js/appcontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ AppController.prototype.hangup_ = function() {
// Reset key and mouse event handlers.
document.onkeypress = null;
window.onmousemove = null;
this.remoteVideo_.srcObject = null;
};

AppController.prototype.onRemoteHangup_ = function() {
Expand Down Expand Up @@ -375,8 +374,6 @@ AppController.prototype.transitionToWaiting_ = function() {
AppController.prototype.transitionToDone_ = function() {
// Stop waiting for remote video.
this.remoteVideo_.oncanplay = undefined;
// Rotate back the video div for rejoin and new room situations.
this.deactivate_(this.videosDiv_);
this.deactivate_(this.localVideo_);
this.deactivate_(this.remoteVideo_);
this.deactivate_(this.miniVideo_);
Expand Down
47 changes: 22 additions & 25 deletions src/web_app/js/call.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
/* exported Call */

'use strict';
// doNotRequestMediaAndIceServers should be set to true if getUserMedia and Ice
// servers should not be request.
var Call = function(params, doNotRequestMediaAndIceServers) {

var Call = function(params) {
this.params_ = params;
this.roomServer_ = params.roomServer || '';

Expand All @@ -43,11 +42,7 @@ var Call = function(params, doNotRequestMediaAndIceServers) {

this.getMediaPromise_ = null;
this.getIceServersPromise_ = null;
// Only request ICE servers and getUserMedia for p2p calls and the 1st
// loopback peerConnection.
if (!doNotRequestMediaAndIceServers) {
this.requestMediaAndIceServers_();
}
this.requestMediaAndIceServers_();
};

Call.prototype.requestMediaAndIceServers_ = function() {
Expand All @@ -61,6 +56,9 @@ Call.prototype.isInitiator = function() {

Call.prototype.start = function(roomId) {
this.connectToRoom_(roomId);
if (this.params_.isLoopback) {
setupLoopback(this.params_.wssUrl, roomId);
}
};

Call.prototype.queueCleanupMessages_ = function() {
Expand Down Expand Up @@ -156,32 +154,32 @@ Call.prototype.hangup = function(async) {
var steps = [];
steps.push({
step: function() {
// Send POST request to /leave.
var path = this.getLeaveUrl_();
return sendUrlRequest('POST', path, async);
}.bind(this),
// Send POST request to /leave.
var path = this.getLeaveUrl_();
return sendUrlRequest('POST', path, async);
}.bind(this),
errorString: 'Error sending /leave:'
});
steps.push({
step: function() {
// Send bye to the other client.
this.channel_.send(JSON.stringify({type: 'bye'}));
}.bind(this),
// Send bye to the other client.
this.channel_.send(JSON.stringify({type: 'bye'}));
}.bind(this),
errorString: 'Error sending bye:'
});
steps.push({
step: function() {
// Close signaling channel.
return this.channel_.close(async);
}.bind(this),
// Close signaling channel.
return this.channel_.close(async);
}.bind(this),
errorString: 'Error closing signaling channel:'
});
steps.push({
step: function() {
this.params_.previousRoomId = this.params_.roomId;
this.params_.roomId = null;
this.params_.clientId = null;
}.bind(this),
this.params_.previousRoomId = this.params_.roomId;
this.params_.roomId = null;
this.params_.clientId = null;
}.bind(this),
errorString: 'Error setting params:'
});

Expand Down Expand Up @@ -234,6 +232,7 @@ Call.prototype.onRemoteHangup = function() {
this.pcClient_.close();
this.pcClient_ = null;
}

this.startSignaling_();
};

Expand Down Expand Up @@ -323,6 +322,7 @@ Call.prototype.connectToRoom_ = function(roomId) {
// already registered with GAE.
Promise.all([channelPromise, joinPromise]).then(function() {
this.channel_.register(this.params_.roomId, this.params_.clientId);

// We only start signaling after we have registered the signaling channel
// and have media and TURN. Since we send candidates as soon as the peer
// connection generates them we need to wait for the signaling channel to be
Expand Down Expand Up @@ -492,9 +492,6 @@ Call.prototype.startSignaling_ = function() {
} else {
this.pcClient_.startAsCallee(this.params_.messages);
}
if (this.params_.isLoopback && this.params_.isInitiator) {
setupLoopback(this.params_);
}
this.maybeReportGetUserMediaErrors_();
}.bind(this))
.catch(function(e) {
Expand Down
121 changes: 65 additions & 56 deletions src/web_app/js/loopback.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
Expand All @@ -12,65 +12,74 @@

'use strict';

function setupLoopback(params) {
trace('Setting up loopback peerConnection client.');
// Reuse the parameters from peerConnection 1 by creating a new object and
// modify it to what's needed for peerConnection 2.
var params_ = JSON.parse(JSON.stringify(params));
params_.clientId = 'LOOPBACK_CLIENT_ID_2';
params_.isInitiator = false;
params_.mediaConstraints.audio = false;
params_.mediaConstraints.video = false;
// For loopback calls we reuse the parameters from peerConnection 1 hence it
// does not need to request ICE servers and also we do not need gUM since the
// remote stream is cloned and used as a local stream for peerConnection 2.
var call = new Call(params_, true);

// Dereference the call object so the peerConnection can be garbage collected.
function deleteCall() {
call = null;
// We handle the loopback case by making a second connection to the WSS so that
// we receive the same messages that we send out. When receiving an offer we
// convert that offer into an answer message. When receiving candidates we
// echo back the candidate. Answer is ignored because we should never receive
// one while in loopback. Bye is ignored because there is no work to do.
var loopbackWebSocket = null;
var LOOPBACK_CLIENT_ID = 'loopback_client_id';
function setupLoopback(wssUrl, roomId) {
if (loopbackWebSocket) {
loopbackWebSocket.close();
}
trace('Setting up loopback WebSocket.');
// TODO(tkchin): merge duplicate code once SignalingChannel abstraction
// exists.
loopbackWebSocket = new WebSocket(wssUrl);

// Hangup peerconnection 2 properly since the UI only controls
// peerconnection 1.
call.onremotehangup = function() {
this.hangup(true);
this.startTime = null;
if (this.pcClient_) {
this.pcClient_.close();
this.pcClient_ = null;
}
deleteCall();
}.bind(call);
var sendLoopbackMessage = function(message) {
var msgString = JSON.stringify({
cmd: 'send',
msg: JSON.stringify(message)
});
loopbackWebSocket.send(msgString);
};

// Add the remote stream from peerConnection 1 as a local stream for
// peerConnection 2 (loopback) before sending an answer to avoid renegotiation
// since peerConnection 2 does not have a access to the stream until
// peerConnection 1 has added it.
call.onremotestreamadded = function(event) {
if (this.params_.clientId === 'LOOPBACK_CLIENT_ID_2') {
// Since this fired once per track we need to make sure it will only add
// the stream once.
if (this.pcClient_.loopBackStream === null) {
// 2nd peerConnection should not be the initiator.
if (!this.params_.isInitiator_) {
this.pcClient_.loopBackStream = event.clone();
// Disable audio tracks on the remote tracks of the remote stream
// otherwise it will be played back by the Chrome mixer as well.
event.getAudioTracks()[0].enabled = false;
this.pcClient_.pc_.addStream(this.pcClient_.loopBackStream);
this.pcClient_.doAnswer_();
}
}
}
}.bind(call);
loopbackWebSocket.onopen = function() {
trace('Loopback WebSocket opened.');
var registerMessage = {
cmd: 'register',
roomid: roomId,
clientid: LOOPBACK_CLIENT_ID
};
loopbackWebSocket.send(JSON.stringify(registerMessage));
};

// Make sure to shutdown peerConnection 2 properly when a user
// closes the tab.
window.onbeforeunload = function() {
call.hangup.bind(call, false);
loopbackWebSocket.onmessage = function(event) {
var wssMessage;
var message;
try {
wssMessage = JSON.parse(event.data);
message = JSON.parse(wssMessage.msg);
} catch (e) {
trace('Error parsing JSON: ' + event.data);
return;
}
if (wssMessage.error) {
trace('WSS error: ' + wssMessage.error);
return;
}
if (message.type === 'offer') {
var loopbackAnswer = wssMessage.msg;
loopbackAnswer = loopbackAnswer.replace('"offer"', '"answer"');
loopbackAnswer =
loopbackAnswer.replace('a=ice-options:google-ice\\r\\n', '');
// As of Chrome M51, an additional crypto method has been added when
// using SDES. This works in a P2P due to the negotiation phase removes
// this line but for loopback where we reuse the offer, that is skipped
// and remains in the answer and breaks the call.
// https://bugs.chromium.org/p/chromium/issues/detail?id=616263
loopbackAnswer = loopbackAnswer
.replace(/a=crypto:0 AES_CM_128_HMAC_SHA1_32\sinline:.{44}/, '');
sendLoopbackMessage(JSON.parse(loopbackAnswer));
} else if (message.type === 'candidate') {
sendLoopbackMessage(message);
}
};

// Start peerConnection 2.
call.start(params_.roomId);
loopbackWebSocket.onclose = function(event) {
trace('Loopback WebSocket closed with code:' + event.code + ' reason:' +
event.reason);
};
}
Loading

0 comments on commit a9b1aff

Please sign in to comment.