浏览代码

everything works

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() {

部分文件因为文件数量过多而无法显示