Michelle Bu 12 лет назад
Родитель
Сommit
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() {

Некоторые файлы не были показаны из-за большого количества измененных файлов