|
@@ -862,11 +862,14 @@ function Peer(options) {
|
|
this._socket = new WebSocket(options.ws);
|
|
this._socket = new WebSocket(options.ws);
|
|
this._socketInit();
|
|
this._socketInit();
|
|
|
|
|
|
- // Connections
|
|
|
|
|
|
+ // Connections for this peer.
|
|
this.connections = {};
|
|
this.connections = {};
|
|
|
|
|
|
- // Queued connections to make
|
|
|
|
|
|
+ // Queued connections to make.
|
|
this._queued = [];
|
|
this._queued = [];
|
|
|
|
+
|
|
|
|
+ // Make sure connections are cleaned up.
|
|
|
|
+ window.onbeforeunload = this._cleanup;
|
|
};
|
|
};
|
|
|
|
|
|
util.inherits(Peer, EventEmitter);
|
|
util.inherits(Peer, EventEmitter);
|
|
@@ -891,7 +894,7 @@ Peer.prototype._socketInit = function() {
|
|
};
|
|
};
|
|
var connection = new DataConnection(self._id, peer, self._socket, function(err, connection) {
|
|
var connection = new DataConnection(self._id, peer, self._socket, function(err, connection) {
|
|
if (!err) {
|
|
if (!err) {
|
|
- self.emit('connection', connection);
|
|
|
|
|
|
+ self.emit('connection', connection, message.metadata);
|
|
}
|
|
}
|
|
}, options);
|
|
}, options);
|
|
self.connections[peer] = connection;
|
|
self.connections[peer] = connection;
|
|
@@ -903,7 +906,7 @@ Peer.prototype._socketInit = function() {
|
|
if (connection) connection.handleCandidate(message);
|
|
if (connection) connection.handleCandidate(message);
|
|
break;
|
|
break;
|
|
case 'LEAVE':
|
|
case 'LEAVE':
|
|
- if (connection) connection.handleLeave(message);
|
|
|
|
|
|
+ if (connection) connection.handleLeave();
|
|
break;
|
|
break;
|
|
case 'PORT':
|
|
case 'PORT':
|
|
if (browserisms == 'Firefox') {
|
|
if (browserisms == 'Firefox') {
|
|
@@ -932,6 +935,15 @@ Peer.prototype._processQueue = function() {
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
+Peer.prototype._cleanup = function() {
|
|
|
|
+ for (var peer in this.connections) {
|
|
|
|
+ if (this.connections.hasOwnProperty(peer)) {
|
|
|
|
+ this.connections[peer].close();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
Peer.prototype.connect = function(peer, metadata, cb) {
|
|
Peer.prototype.connect = function(peer, metadata, cb) {
|
|
if (typeof metadata === 'function' && !cb) cb = metadata; metadata = false;
|
|
if (typeof metadata === 'function' && !cb) cb = metadata; metadata = false;
|
|
|
|
|
|
@@ -1066,17 +1078,9 @@ DataConnection.prototype.handleCandidate = function(message) {
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
-DataConnection.prototype.handleLeave = function(message) {
|
|
|
|
|
|
+DataConnection.prototype.handleLeave = function() {
|
|
util.log('Peer ' + this._peer + ' disconnected');
|
|
util.log('Peer ' + this._peer + ' disconnected');
|
|
- if (!!this._pc && this._pc.readyState != 'closed') {
|
|
|
|
- this._pc.close();
|
|
|
|
- this._pc = null;
|
|
|
|
- }
|
|
|
|
- if (!!this._dc && this._dc.readyState != 'closed') {
|
|
|
|
- this._dc.close();
|
|
|
|
- this._dc = null;
|
|
|
|
- }
|
|
|
|
- this.emit('close', this._peer);
|
|
|
|
|
|
+ this._cleanup();
|
|
};
|
|
};
|
|
|
|
|
|
DataConnection.prototype.handlePort = function(message) {
|
|
DataConnection.prototype.handlePort = function(message) {
|
|
@@ -1114,6 +1118,7 @@ DataConnection.prototype._setupIce = function() {
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
+// Awaiting update in Firefox spec ***
|
|
/** Sets up DataChannel handlers.
|
|
/** Sets up DataChannel handlers.
|
|
DataConnection.prototype._setupDataChannel = function() {
|
|
DataConnection.prototype._setupDataChannel = function() {
|
|
var self = this;
|
|
var self = this;
|
|
@@ -1205,7 +1210,7 @@ DataConnection.prototype._makeOffer = function() {
|
|
sdp: offer,
|
|
sdp: offer,
|
|
dst: self._peer,
|
|
dst: self._peer,
|
|
src: self._id,
|
|
src: self._id,
|
|
- metadata: self._metadata
|
|
|
|
|
|
+ metadata: self.metadata
|
|
}));
|
|
}));
|
|
}, function(err) {
|
|
}, function(err) {
|
|
self._cb('Failed to setLocalDescription');
|
|
self._cb('Failed to setLocalDescription');
|
|
@@ -1238,8 +1243,31 @@ DataConnection.prototype._makeAnswer = function() {
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
+DataConnection.prototype._cleanup = function() {
|
|
|
|
+ if (!!this._pc && this._pc.readyState != 'closed') {
|
|
|
|
+ this._pc.close();
|
|
|
|
+ this._pc = null;
|
|
|
|
+ }
|
|
|
|
+ if (!!this._dc && this._dc.readyState != 'closed') {
|
|
|
|
+ this._dc.close();
|
|
|
|
+ this._dc = null;
|
|
|
|
+ }
|
|
|
|
+ this.emit('close', this._peer);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
+/** Allows user to close connection. */
|
|
|
|
+DataConnection.prototype.close = function() {
|
|
|
|
+ this._cleanup();
|
|
|
|
+ var self = this;
|
|
|
|
+ this._socket.send(JSON.stringify({
|
|
|
|
+ type: 'LEAVE',
|
|
|
|
+ dst: self._peer,
|
|
|
|
+ src: self._id,
|
|
|
|
+ }));
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
|
|
/** Allows user to send data. */
|
|
/** Allows user to send data. */
|
|
DataConnection.prototype.send = function(data) {
|
|
DataConnection.prototype.send = function(data) {
|