Permalink
Browse files

firefox basic connectivity working. #24

  • Loading branch information...
1 parent e62559e commit f7314a30d5ff87db3ff0c68aa79ead68e7102adb @michelle michelle committed Mar 31, 2013
Showing with 201 additions and 33 deletions.
  1. +125 −19 dist/peer.js
  2. +1 −1 dist/peer.min.js
  3. +66 −7 lib/connectionmanager.js
  4. +1 −0 lib/dataconnection.js
  5. +7 −5 lib/peer.js
  6. +1 −1 lib/util.js
View
@@ -721,7 +721,7 @@ EventEmitter.prototype.emit = function(type) {
var util = {
chromeCompatible: true,
- firefoxCompatible: false,
+ firefoxCompatible: true,
chromeVersion: 26,
firefoxVersion: 22,
@@ -1287,6 +1287,12 @@ Peer.prototype._handleServerJSONMessage = function(message) {
var peer = message.src;
var manager = this.managers[peer];
var payload = message.payload;
+
+ // Check that browsers match.
+ if (!!payload && !!payload.browserisms && payload.browserisms !== util.browserisms) {
+ this._warn('incompatible-peer', 'Peer ' + self.peer + ' is on an incompatible browser. Please clean up this peer.');
+ }
+
switch (message.type) {
case 'OPEN':
this._processQueue();
@@ -1341,10 +1347,11 @@ Peer.prototype._handleServerJSONMessage = function(message) {
this._abort('invalid-key', 'API KEY "' + this._key + '" is invalid');
break;
case 'PORT':
- //if (util.browserisms === 'Firefox') {
- // connection.handlePort(payload);
- // break;
- //}
+ // Firefoxism: exchanging ports.
+ if (util.browserisms === 'Firefox' && manager) {
+ manager.handlePort(payload);
+ break;
+ }
default:
util.log('Unrecognized message type:', message.type);
break;
@@ -1385,6 +1392,12 @@ Peer.prototype._abort = function(type, message) {
this.destroy();
this.emit('error', err);
};
+/** Emits an error message that things may not work. */
+Peer.prototype._warn = function(type, message) {
+ var err = new Error(message);
+ err.type = type;
+ this.emit('error', err);
+};
Peer.prototype._cleanup = function() {
var self = this;
@@ -1406,15 +1419,14 @@ Peer.prototype._cleanup = function() {
* is waiting for an ID. */
Peer.prototype.connect = function(peer, options) {
if (this.disconnected) {
- var err = new Error('This Peer has been disconnected from the server and');
- err.type = 'peer-disconnected';
- this.emit('error', err);
+ this._warn('peer-disconnected', 'This Peer has been disconnected from the server and');
return;
}
options = util.extend({
config: this._options.config
}, options);
+ options.originator = true;
var manager = this.managers[peer];
if (!manager) {
@@ -1493,6 +1505,7 @@ function DataConnection(peer, dc, options) {
util.inherits(DataConnection, EventEmitter);
DataConnection.prototype._configureDataChannel = function() {
+ util.log('Configuring DataChannel with peer ' + this.peer);
var self = this;
if (util.browserisms !== 'Webkit') {
this._dc.binaryType = 'arraybuffer';
@@ -1651,25 +1664,80 @@ ConnectionManager.prototype.initialize = function(id, socket) {
this._socket = socket;
}
+ // Firefoxism where ports need to be generated.
+ if (util.browserisms === 'Firefox') {
+ this._firefoxPortSetup();
+ }
+
// Set up PeerConnection.
this._startPeerConnection();
// Process queued DCs.
- this._processQueue();
+ if (util.browserisms !== 'Firefox') {
+ this._processQueue();
+ }
// Listen for ICE candidates.
this._setupIce();
- // Listen for negotiation needed.
- // Chrome only **
- this._setupNegotiationHandler();
-
// Listen for data channel.
this._setupDataChannel();
+ // Listen for negotiation needed.
+ // Chrome only--Firefox instead has to manually makeOffer.
+ if (util.browserisms !== 'Firefox') {
+ this._setupNegotiationHandler();
+ } else if (this._options.originator) {
+ this._firefoxHandlerSetup()
+ this._firefoxAdditional()
+ }
+
this.initialize = function() { };
};
+/** Firefoxism that requires a fake media stream. */
+ConnectionManager.prototype._firefoxAdditional = function() {
+ util.log('Additional media stream for Firefox.');
+ var self = this;
+ getUserMedia({ audio: true, fake: true }, function(s) {
+ self.pc.addStream(s);
+ if (self._options.originator) {
+ self._makeOffer();
+ } else {
+ self._makeAnswer();
+ }
+ }, function(err) { util.log('Could not getUserMedia'); });
+};
+
+/** Firefoxism that requires ports to be set up. */
+ConnectionManager.prototype._firefoxPortSetup = function() {
+ if (!ConnectionManager.usedPorts) {
+ ConnectionManager.usedPorts = [];
+ }
+ this._localPort = util.randomPort();
+ while (ConnectionManager.usedPorts.indexOf(this._localPort) != -1) {
+ this._localPort = util.randomPort();
+ }
+ this._remotePort = util.randomPort();
+ while (this._remotePort === this._localPort ||
+ ConnectionManager.usedPorts.indexOf(this._remotePort) != -1) {
+ this._remotePort = util.randomPort();
+ }
+ ConnectionManager.usedPorts.push(this._remotePort);
+ ConnectionManager.usedPorts.push(this._localPort);
+};
+
+/** Firefoxism that is `onconnection`. */
+ConnectionManager.prototype._firefoxHandlerSetup = function() {
+ util.log('Setup Firefox `onconnection`.');
+ var self = this;
+ this.pc.onconnection = function() {
+ util.log('FIREFOX: onconnection triggered');
+
+ self._processQueue();
+ }
+};
+
/** Start a PC. */
ConnectionManager.prototype._startPeerConnection = function() {
util.log('Creating RTCPeerConnection');
@@ -1718,11 +1786,15 @@ ConnectionManager.prototype._setupDataChannel = function() {
util.log('Listening for data channel');
this.pc.ondatachannel = function(evt) {
util.log('Received data channel');
- var dc = evt.channel;
+ // Firefoxism: ondatachannel receives channel directly. NOT TO SPEC.
+ var dc = util.browserisms === 'Firefox' ? evt : evt.channel;
var label = dc.label;
+
// This should not be empty.
var options = self.labels[label] || {};
var connection = new DataConnection(self.peer, dc, options);
+ delete self.labels[label];
+
self._attachConnectionListeners(connection);
self.connections[label] = connection;
self.emit('connection', connection);
@@ -1739,6 +1811,7 @@ ConnectionManager.prototype._makeOffer = function() {
self._socket.send({
type: 'OFFER',
payload: {
+ browserisms: util.browserisms,
sdp: offer,
config: self._options.config,
labels: self.labels
@@ -1764,6 +1837,7 @@ ConnectionManager.prototype._makeAnswer = function() {
self._socket.send({
type: 'ANSWER',
payload: {
+ browserisms: util.browserisms,
sdp: answer
},
dst: self.peer
@@ -1810,19 +1884,51 @@ ConnectionManager.prototype._attachConnectionListeners = function(connection) {
});
connection.on('open', function() {
self._lock = false;
- self._processQueue();
+ if (util.browserisms !== 'Firefox') {
+ self._processQueue();
+ }
});
};
+/** Firefoxism: handle receiving a set of ports. */
+ConnectionManager.prototype.handlePort = function(ports) {
+ util.log('Received ports, calling connectDataConnection.');
+ if (!ConnectionManager.usedPorts) {
+ ConnectionManager.usedPorts = [];
+ }
+ ConnectionManager.usedPorts.push(ports.local);
+ ConnectionManager.usedPorts.push(ports.remote);
+ this.pc.connectDataConnection(ports.local, ports.remote);
+};
+
/** Handle an SDP. */
ConnectionManager.prototype.handleSDP = function(sdp, type) {
- sdp = new RTCSessionDescription(sdp);
+ if (util.browserisms !== 'Firefox') {
+ // Doesn't need to happen for FF.
+ sdp = new RTCSessionDescription(sdp);
+ }
var self = this;
this.pc.setRemoteDescription(sdp, function() {
util.log('Set remoteDescription: ' + type);
if (type === 'OFFER') {
- self._makeAnswer();
+ if (util.browserisms === 'Firefox') {
+ self._firefoxAdditional();
+ } else {
+ self._makeAnswer();
+ }
+ } else if (util.browserisms === 'Firefox') {
+ // Firefoxism.
+ util.log('Peer ANSWER received, connectDataConnection called.');
+ self.pc.connectDataConnection(self._localPort, self._remotePort);
+ self._socket.send({
+ type: 'PORT',
+ payload: {
+ remote: self._localPort,
+ local: self._remotePort
+ },
+ dst: self.peer
+ });
}
}, function(err) {
self.emit('error', err);
@@ -1879,14 +1985,14 @@ ConnectionManager.prototype.connect = function(options) {
this.labels[options.label] = options;
var dc;
- if (!!this.pc && !this._lock) {
+ if (!!this.pc && !this._lock && util.browserisms !== 'Firefox') {
dc = this.pc.createDataChannel(options.label, { reliable: false });
}
var connection = new DataConnection(this.peer, dc, options);
this._attachConnectionListeners(connection);
this.connections[options.label] = connection;
- if (!this.pc || this._lock) {
+ if (!this.pc || this._lock || util.browserisms === 'Firefox') {
this._queued.push(connection);
}
View

Large diffs are not rendered by default.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit f7314a3

Please sign in to comment.