Michelle Bu преди 12 години
родител
ревизия
d62aed692d
променени са 6 файла, в които са добавени 148 реда и са изтрити 49 реда
  1. 72 23
      dist/peer.js
  2. 0 0
      dist/peer.min.js
  3. 4 3
      docs/api.md
  4. 50 14
      lib/connectionmanager.js
  5. 11 4
      lib/dataconnection.js
  6. 11 5
      lib/peer.js

+ 72 - 23
dist/peer.js

@@ -1315,10 +1315,17 @@ Peer.prototype._processQueue = function() {
 /** Listeners for manager. */
 Peer.prototype._attachManagerListeners = function(manager) {
   var self = this;
+  // Handle receiving a connection.
   manager.on('connection', function(connection) {
     self.connections[connection.peer][connection.label] = connection;
     self.emit('connection', connection);
   });
+  // Handle a connection closing.
+  manager.on('close', function() {
+    if (!!self.managers[manager.peer]) {
+      delete self.managers[manager.peer]
+    }
+  });
   manager.on('error', function(err) {
     self.emit('error', err);
   });
@@ -1371,16 +1378,15 @@ Peer.prototype.connect = function(peer, options) {
     this.connections[peer] = {};
   }
 
-  var connection = manager.connect(options.label);
-  console.log(peer, options.label);
-  if (!!connection) {
-    this.connections[peer][options.label] = connection;
+  var connectionInfo = manager.connect(options.label);
+  if (!!connectionInfo) {
+    this.connections[peer][connectionInfo[0]] = connectionInfo[1];
   }
 
   if (!this.id) {
     this._queued.push(manager);
   }
-  return connection;
+  return connectionInfo[1];
 };
 
 Peer.prototype.destroy = function() {
@@ -1441,7 +1447,8 @@ DataConnection.prototype._configureDataChannel = function() {
     };
   }
   this._dc.onclose = function(e) {
-    self.emit('close');
+    util.log('DataChannel closed.');
+    self.close();
   };
 
   // Reliable.
@@ -1452,10 +1459,12 @@ DataConnection.prototype._configureDataChannel = function() {
 };
 
 DataConnection.prototype._cleanup = function() {
-  if (!!this._dc && this._dc.readyState != 'closed') {
+  if (!!this._dc && this._dc.readyState !== 'closed') {
     this._dc.close();
     this._dc = null;
   }
+  this.open = false;
+  this.emit('close');
 };
 
 // Handles a DataChannel message.
@@ -1494,13 +1503,17 @@ DataConnection.prototype.addDC = function(dc) {
 
 /** Allows user to close connection. */
 DataConnection.prototype.close = function() {
+  if (!this.open) {
+    return;
+  }
   this._cleanup();
-  this.open = false;
-  this.emit('close');
 };
 
 /** Allows user to send data. */
 DataConnection.prototype.send = function(data) {
+  if (!this.open) {
+    this.emit('error', new Error('Connection no longer open.'));
+  }
   if (this._reliable) {
     // Note: reliable sending will make it so that you cannot customize
     // serialization.
@@ -1547,7 +1560,9 @@ function ConnectionManager(id, peer, socket, options) {
 
   // Mapping labels to metadata and serialization.
   // label => { metadata: ..., serialization: ..., reliable: ...}
-  this.labels = {}
+  this.labels = {};
+  // A default label in the event that none are passed in.
+  this._default = 0;
 
   // DataConnections on this PC.
   this.connections = {};
@@ -1642,6 +1657,7 @@ ConnectionManager.prototype._setupDataChannel = function() {
     // This should not be empty.
     var options = self.labels[label] || {};
     var connection  = new DataConnection(self.peer, dc, options);
+    self._attachConnectionListeners(connection);
     self.connections[label] = connection;
     self.emit('connection', connection);
   };
@@ -1699,7 +1715,33 @@ ConnectionManager.prototype._makeAnswer = function() {
 /** Clean up PC, close related DCs. */
 ConnectionManager.prototype._cleanup = function() {
   util.log('Cleanup ConnectionManager for ' + this.peer);
+  if (!!this.pc && this.pc.readyState !== 'closed') {
+    this.pc.close();
+    this.pc = null;
+  }
+
+  var self = this;
+  this._socket.send({
+    type: 'LEAVE',
+    dst: self.peer
+  });
 
+  this.open = false;
+  this.emit('close');
+};
+
+/** Attach connection listeners. */
+ConnectionManager.prototype._attachConnectionListeners = function(connection) {
+  var self = this;
+  connection.on('close', function() {
+    if (!!self.connections[connection.label]) {
+      delete self.connections[connection.label];
+    }
+
+    if (!Object.keys(self.connections).length) {
+      self._cleanup();
+    }
+  });
 };
 
 /** Handle an SDP. */
@@ -1733,25 +1775,31 @@ ConnectionManager.prototype.handleLeave = function() {
 
 /** Closes manager and all related connections. */
 ConnectionManager.prototype.close = function() {
-  this._cleanup();
-  var self = this;
-  if (this.open) {
-    this._socket.send({
-      type: 'LEAVE',
-      dst: self.peer
-    });
+  if (!this.open) {
+    this.emit('error', new Error('Connections to ' + this.peer + 'are already closed.'));
+    return;
   }
-  this.open = false;
-  this.emit('close', this.peer);
+
+  var labels = Object.keys(this.connections);
+  for (var i = 0, ii = labels.length; i < ii; i += 1) {
+    var label = labels[i];
+    var connection = this.connections[label];
+    connection.close();
+  }
+  this.connections = null;
+  this._cleanup();
 };
 
 /** Create and returns a DataConnection with the peer with the given label. */
 ConnectionManager.prototype.connect = function(label, options) {
-  // Check if label is taken.
-  if (!!this.connections[label]) {
-    this.emit('error', new Error('Label name taken for peer: ' + this.peer));
+  if (!this.open) {
     return;
   }
+  // Check if label is taken...if so, generate a new label randomly.
+  while (!!this.connections[label]) {
+    label = 'peerjs' + this._default;
+    this._default += 1;
+  }
 
   options = util.extend({
     reliable: false,
@@ -1766,12 +1814,13 @@ ConnectionManager.prototype.connect = function(label, options) {
     dc = this.pc.createDataChannel(label, { reliable: false });
   }
   var connection = new DataConnection(this.peer, dc, options);
+  this._attachConnectionListeners(connection);
   this.connections[label] = connection;
 
   if (!this.pc) {
     this._queued.push(connection);
   }
-  return connection;
+  return [label, connection];
 };
 
 /** Updates label:[serialization, reliable, metadata] pairs from offer. */

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
dist/peer.min.js


+ 4 - 3
docs/api.md

@@ -77,7 +77,8 @@ This event does not need to fire before creating or receiving connections.
 
 `function (error) { }`
 
-Emitted when an unexpected event occurs. Errors on the Peer are **always fatal**. Errors from the underlying socket are forwarded here.
+Emitted when an unexpected event occurs. Errors on the Peer are **always
+fatal**. Errors from the underlying socket and PeerConnections are forwarded here.
 
 The `error` object also has a `type` parameter that may be helpful in responding to client errors properly:
 * `invalid-id`: The ID passed into the Peer constructor contains illegal characters.
@@ -94,7 +95,7 @@ The `error` object also has a `type` parameter that may be helpful in responding
 
 `function () { }`
 
-Emitted when the Peer object has closed it's connection with PeerServer so no more remote peer connections can be made or received.
+Emitted when the Peer object has closed its connection with PeerServer so no more remote peer connections can be made or received.
 
 To be extra certain that Peer objects clean up cleanly (and because it takes the WS server and DataChannel some time to realize that a Peer has disconnected), it is best to call `destroy()` on a Peer when it is no longer needed.
 
@@ -161,7 +162,7 @@ Emitted when the connection is established and ready for writing. `data` from th
 
 `function (error) { }`
 
-If the client emits an error, this event is emitted (errors from the underlying `RTCPeerConnection` and `DataChannel` are forwarded here).
+If the client emits an error, this event is emitted (errors from the underlying `DataChannel` are forwarded here).
 
 `error` is an `Error` object.
 

+ 50 - 14
lib/connectionmanager.js

@@ -20,7 +20,9 @@ function ConnectionManager(id, peer, socket, options) {
 
   // Mapping labels to metadata and serialization.
   // label => { metadata: ..., serialization: ..., reliable: ...}
-  this.labels = {}
+  this.labels = {};
+  // A default label in the event that none are passed in.
+  this._default = 0;
 
   // DataConnections on this PC.
   this.connections = {};
@@ -115,6 +117,7 @@ ConnectionManager.prototype._setupDataChannel = function() {
     // This should not be empty.
     var options = self.labels[label] || {};
     var connection  = new DataConnection(self.peer, dc, options);
+    self._attachConnectionListeners(connection);
     self.connections[label] = connection;
     self.emit('connection', connection);
   };
@@ -172,7 +175,33 @@ ConnectionManager.prototype._makeAnswer = function() {
 /** Clean up PC, close related DCs. */
 ConnectionManager.prototype._cleanup = function() {
   util.log('Cleanup ConnectionManager for ' + this.peer);
+  if (!!this.pc && this.pc.readyState !== 'closed') {
+    this.pc.close();
+    this.pc = null;
+  }
+
+  var self = this;
+  this._socket.send({
+    type: 'LEAVE',
+    dst: self.peer
+  });
+
+  this.open = false;
+  this.emit('close');
+};
+
+/** Attach connection listeners. */
+ConnectionManager.prototype._attachConnectionListeners = function(connection) {
+  var self = this;
+  connection.on('close', function() {
+    if (!!self.connections[connection.label]) {
+      delete self.connections[connection.label];
+    }
 
+    if (!Object.keys(self.connections).length) {
+      self._cleanup();
+    }
+  });
 };
 
 /** Handle an SDP. */
@@ -206,25 +235,31 @@ ConnectionManager.prototype.handleLeave = function() {
 
 /** Closes manager and all related connections. */
 ConnectionManager.prototype.close = function() {
-  this._cleanup();
-  var self = this;
-  if (this.open) {
-    this._socket.send({
-      type: 'LEAVE',
-      dst: self.peer
-    });
+  if (!this.open) {
+    this.emit('error', new Error('Connections to ' + this.peer + 'are already closed.'));
+    return;
   }
-  this.open = false;
-  this.emit('close', this.peer);
+
+  var labels = Object.keys(this.connections);
+  for (var i = 0, ii = labels.length; i < ii; i += 1) {
+    var label = labels[i];
+    var connection = this.connections[label];
+    connection.close();
+  }
+  this.connections = null;
+  this._cleanup();
 };
 
 /** Create and returns a DataConnection with the peer with the given label. */
 ConnectionManager.prototype.connect = function(label, options) {
-  // Check if label is taken.
-  if (!!this.connections[label]) {
-    this.emit('error', new Error('Label name taken for peer: ' + this.peer));
+  if (!this.open) {
     return;
   }
+  // Check if label is taken...if so, generate a new label randomly.
+  while (!!this.connections[label]) {
+    label = 'peerjs' + this._default;
+    this._default += 1;
+  }
 
   options = util.extend({
     reliable: false,
@@ -239,12 +274,13 @@ ConnectionManager.prototype.connect = function(label, options) {
     dc = this.pc.createDataChannel(label, { reliable: false });
   }
   var connection = new DataConnection(this.peer, dc, options);
+  this._attachConnectionListeners(connection);
   this.connections[label] = connection;
 
   if (!this.pc) {
     this._queued.push(connection);
   }
-  return connection;
+  return [label, connection];
 };
 
 /** Updates label:[serialization, reliable, metadata] pairs from offer. */

+ 11 - 4
lib/dataconnection.js

@@ -47,7 +47,8 @@ DataConnection.prototype._configureDataChannel = function() {
     };
   }
   this._dc.onclose = function(e) {
-    self.emit('close');
+    util.log('DataChannel closed.');
+    self.close();
   };
 
   // Reliable.
@@ -58,10 +59,12 @@ DataConnection.prototype._configureDataChannel = function() {
 };
 
 DataConnection.prototype._cleanup = function() {
-  if (!!this._dc && this._dc.readyState != 'closed') {
+  if (!!this._dc && this._dc.readyState !== 'closed') {
     this._dc.close();
     this._dc = null;
   }
+  this.open = false;
+  this.emit('close');
 };
 
 // Handles a DataChannel message.
@@ -100,13 +103,17 @@ DataConnection.prototype.addDC = function(dc) {
 
 /** Allows user to close connection. */
 DataConnection.prototype.close = function() {
+  if (!this.open) {
+    return;
+  }
   this._cleanup();
-  this.open = false;
-  this.emit('close');
 };
 
 /** Allows user to send data. */
 DataConnection.prototype.send = function(data) {
+  if (!this.open) {
+    this.emit('error', new Error('Connection no longer open.'));
+  }
   if (this._reliable) {
     // Note: reliable sending will make it so that you cannot customize
     // serialization.

+ 11 - 5
lib/peer.js

@@ -178,10 +178,17 @@ Peer.prototype._processQueue = function() {
 /** Listeners for manager. */
 Peer.prototype._attachManagerListeners = function(manager) {
   var self = this;
+  // Handle receiving a connection.
   manager.on('connection', function(connection) {
     self.connections[connection.peer][connection.label] = connection;
     self.emit('connection', connection);
   });
+  // Handle a connection closing.
+  manager.on('close', function() {
+    if (!!self.managers[manager.peer]) {
+      delete self.managers[manager.peer]
+    }
+  });
   manager.on('error', function(err) {
     self.emit('error', err);
   });
@@ -234,16 +241,15 @@ Peer.prototype.connect = function(peer, options) {
     this.connections[peer] = {};
   }
 
-  var connection = manager.connect(options.label);
-  console.log(peer, options.label);
-  if (!!connection) {
-    this.connections[peer][options.label] = connection;
+  var connectionInfo = manager.connect(options.label);
+  if (!!connectionInfo) {
+    this.connections[peer][connectionInfo[0]] = connectionInfo[1];
   }
 
   if (!this.id) {
     this._queued.push(manager);
   }
-  return connection;
+  return connectionInfo[1];
 };
 
 Peer.prototype.destroy = function() {

Някои файлове не бяха показани, защото твърде много файлове са промени