|
@@ -139,44 +139,54 @@ Peer.prototype._initialize = function(id) {
|
|
/** Handles messages from the server. */
|
|
/** Handles messages from the server. */
|
|
Peer.prototype._handleMessage = function(message) {
|
|
Peer.prototype._handleMessage = function(message) {
|
|
var type = message.type;
|
|
var type = message.type;
|
|
- var payload = message.payload
|
|
|
|
|
|
+ var payload = message.payload;
|
|
|
|
+ var peer = message.src;
|
|
|
|
+
|
|
switch (type) {
|
|
switch (type) {
|
|
- case 'OPEN':
|
|
|
|
- this._processQueue();
|
|
|
|
|
|
+ case 'OPEN': // The connection to the server is open.
|
|
this.emit('open', this.id);
|
|
this.emit('open', this.id);
|
|
break;
|
|
break;
|
|
- case 'ERROR':
|
|
|
|
|
|
+ case 'ERROR': // Server error.
|
|
this._abort('server-error', payload.msg);
|
|
this._abort('server-error', payload.msg);
|
|
break;
|
|
break;
|
|
- case 'ID-TAKEN':
|
|
|
|
|
|
+ case 'ID-TAKEN': // The selected ID is taken.
|
|
this._abort('unavailable-id', 'ID `' + this.id + '` is taken');
|
|
this._abort('unavailable-id', 'ID `' + this.id + '` is taken');
|
|
break;
|
|
break;
|
|
- case 'INVALID-KEY':
|
|
|
|
|
|
+ case 'INVALID-KEY': // The given API key cannot be found.
|
|
this._abort('invalid-key', 'API KEY "' + this._key + '" is invalid');
|
|
this._abort('invalid-key', 'API KEY "' + this._key + '" is invalid');
|
|
break;
|
|
break;
|
|
|
|
+
|
|
|
|
+ case 'LEAVE': // Another peer has closed its connection to this peer.
|
|
|
|
+ this._cleanupPeer(peer);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 'EXPIRE': // The offer sent to a peer has expired without response.
|
|
|
|
+ // TODO: should this be on the DataConnection? It's currently here but I'm not so sure it belongs.
|
|
|
|
+ this.emit('error', new Error('Could not connect to peer ' + peer));
|
|
|
|
+ break;
|
|
case 'OFFER': // we should consider switching this to CALL/CONNECT, but this is the least breaking option.
|
|
case 'OFFER': // we should consider switching this to CALL/CONNECT, but this is the least breaking option.
|
|
- var peer = message.src;
|
|
|
|
var id = message.id;
|
|
var id = message.id;
|
|
var connection = this._getConnection(peer, id);
|
|
var connection = this._getConnection(peer, id);
|
|
|
|
|
|
if (connection) {
|
|
if (connection) {
|
|
// Pass it on
|
|
// Pass it on
|
|
|
|
+ // TODO: is this just a no-op for DataConnection then? I am under the
|
|
|
|
+ // impression that only MediaConnection need to renegotiate. I'm not
|
|
|
|
+ // even sure how a DataConnection would handle renegotiation.
|
|
connection.handleMessage(message);
|
|
connection.handleMessage(message);
|
|
} else {
|
|
} else {
|
|
// Create a new connection.
|
|
// Create a new connection.
|
|
if (payload.type === 'call') {
|
|
if (payload.type === 'call') {
|
|
var call = new MediaConnection(peer, {
|
|
var call = new MediaConnection(peer, {
|
|
id: id,
|
|
id: id,
|
|
- offer: offer,
|
|
|
|
- sdp: payload.sdp
|
|
|
|
|
|
+ offer: payload.sdp
|
|
});
|
|
});
|
|
this._addConnection(peer, call);
|
|
this._addConnection(peer, call);
|
|
this.emit('call', call);
|
|
this.emit('call', call);
|
|
} else if (payload.type === 'connect') {
|
|
} else if (payload.type === 'connect') {
|
|
var connection = new DataConnection(peer, {
|
|
var connection = new DataConnection(peer, {
|
|
id: id,
|
|
id: id,
|
|
- offer: offer,
|
|
|
|
- sdp: payload.sdp,
|
|
|
|
|
|
+ offer: payload.sdp,
|
|
config: this.options.config
|
|
config: this.options.config
|
|
});
|
|
});
|
|
this._addConnection(peer, connection);
|
|
this._addConnection(peer, connection);
|
|
@@ -187,7 +197,6 @@ Peer.prototype._handleMessage = function(message) {
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- var peer = message.src;
|
|
|
|
var id = message.id;
|
|
var id = message.id;
|
|
var connection = this._getConnection(peer, id);
|
|
var connection = this._getConnection(peer, id);
|
|
|
|
|
|
@@ -200,12 +209,20 @@ Peer.prototype._handleMessage = function(message) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Returns a DataConnection to the specified peer. See documentation for a
|
|
|
|
+ * complete list of options.
|
|
|
|
+ */
|
|
Peer.prototype.connect = function(peer, options) {
|
|
Peer.prototype.connect = function(peer, options) {
|
|
var connection = new DataConnection(peer, options);
|
|
var connection = new DataConnection(peer, options);
|
|
this._addConnection(peer, connection);
|
|
this._addConnection(peer, connection);
|
|
return connection;
|
|
return connection;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Returns a MediaConnection to the specified peer. See documentation for a
|
|
|
|
+ * complete list of options.
|
|
|
|
+ */
|
|
Peer.prototype.call = function(peer, stream, options) {
|
|
Peer.prototype.call = function(peer, stream, options) {
|
|
if (!stream) {
|
|
if (!stream) {
|
|
util.error('To call a peer, you must provide a stream from your browser\'s `getUserMedia`.');
|
|
util.error('To call a peer, you must provide a stream from your browser\'s `getUserMedia`.');
|
|
@@ -217,6 +234,7 @@ Peer.prototype.call = function(peer, stream, options) {
|
|
return call;
|
|
return call;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/** Add a data/media connection to this peer. */
|
|
Peer.prototype._addConnection = function(peer, connection) {
|
|
Peer.prototype._addConnection = function(peer, connection) {
|
|
if (!this.connections[peer]) {
|
|
if (!this.connections[peer]) {
|
|
this.connections[peer] = [];
|
|
this.connections[peer] = [];
|
|
@@ -224,6 +242,7 @@ Peer.prototype._addConnection = function(peer, connection) {
|
|
this.connections[peer].push(connection);
|
|
this.connections[peer].push(connection);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/** Retrieve a data/media connection for this peer. */
|
|
Peer.prototype._getConnection = function(peer, id) {
|
|
Peer.prototype._getConnection = function(peer, id) {
|
|
var connections = this.connections[peer];
|
|
var connections = this.connections[peer];
|
|
if (!connections) {
|
|
if (!connections) {
|
|
@@ -268,18 +287,23 @@ Peer.prototype.destroy = function() {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-/* Disconnects every connection on this peer. */
|
|
|
|
|
|
+/** Disconnects every connection on this peer. */
|
|
Peer.prototype._cleanup = function() {
|
|
Peer.prototype._cleanup = function() {
|
|
var peers = Object.keys(this.connections);
|
|
var peers = Object.keys(this.connections);
|
|
for (var i = 0, ii = peers.length; i < ii; i++) {
|
|
for (var i = 0, ii = peers.length; i < ii; i++) {
|
|
- var connections = this.connections[peers[i]];
|
|
|
|
- for (var j = 0, jj = connections; j < jj; j++) {
|
|
|
|
- connections[j].close();
|
|
|
|
- }
|
|
|
|
|
|
+ this._cleanupPeer(peers[i]);
|
|
}
|
|
}
|
|
this.emit('close');
|
|
this.emit('close');
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/** Closes all connections to this peer. */
|
|
|
|
+Peer.prototype._cleanupPeer = function(peer) {
|
|
|
|
+ var connections = this.connections[peer];
|
|
|
|
+ for (var j = 0, jj = connections; j < jj; j += 1) {
|
|
|
|
+ connections[j].close();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Disconnects the Peer's connection to the PeerServer. Does not close any
|
|
* Disconnects the Peer's connection to the PeerServer. Does not close any
|
|
* active connections.
|
|
* active connections.
|