Skip to content

Commit

Permalink
everything works
Browse files Browse the repository at this point in the history
  • Loading branch information
michelle committed Mar 24, 2013
1 parent 5b2c510 commit d62aed6
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 50 deletions.
95 changes: 72 additions & 23 deletions dist/peer.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1315,10 +1315,17 @@ Peer.prototype._processQueue = function() {
/** Listeners for manager. */ /** Listeners for manager. */
Peer.prototype._attachManagerListeners = function(manager) { Peer.prototype._attachManagerListeners = function(manager) {
var self = this; var self = this;
// Handle receiving a connection.
manager.on('connection', function(connection) { manager.on('connection', function(connection) {
self.connections[connection.peer][connection.label] = connection; self.connections[connection.peer][connection.label] = connection;
self.emit('connection', 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) { manager.on('error', function(err) {
self.emit('error', err); self.emit('error', err);
}); });
Expand Down Expand Up @@ -1371,16 +1378,15 @@ Peer.prototype.connect = function(peer, options) {
this.connections[peer] = {}; this.connections[peer] = {};
} }


var connection = manager.connect(options.label); var connectionInfo = manager.connect(options.label);
console.log(peer, options.label); if (!!connectionInfo) {
if (!!connection) { this.connections[peer][connectionInfo[0]] = connectionInfo[1];
this.connections[peer][options.label] = connection;
} }


if (!this.id) { if (!this.id) {
this._queued.push(manager); this._queued.push(manager);
} }
return connection; return connectionInfo[1];
}; };


Peer.prototype.destroy = function() { Peer.prototype.destroy = function() {
Expand Down Expand Up @@ -1441,7 +1447,8 @@ DataConnection.prototype._configureDataChannel = function() {
}; };
} }
this._dc.onclose = function(e) { this._dc.onclose = function(e) {
self.emit('close'); util.log('DataChannel closed.');
self.close();
}; };


// Reliable. // Reliable.
Expand All @@ -1452,10 +1459,12 @@ DataConnection.prototype._configureDataChannel = function() {
}; };


DataConnection.prototype._cleanup = function() { DataConnection.prototype._cleanup = function() {
if (!!this._dc && this._dc.readyState != 'closed') { if (!!this._dc && this._dc.readyState !== 'closed') {
this._dc.close(); this._dc.close();
this._dc = null; this._dc = null;
} }
this.open = false;
this.emit('close');
}; };


// Handles a DataChannel message. // Handles a DataChannel message.
Expand Down Expand Up @@ -1494,13 +1503,17 @@ DataConnection.prototype.addDC = function(dc) {


/** Allows user to close connection. */ /** Allows user to close connection. */
DataConnection.prototype.close = function() { DataConnection.prototype.close = function() {
if (!this.open) {
return;
}
this._cleanup(); this._cleanup();
this.open = false;
this.emit('close');
}; };


/** Allows user to send data. */ /** Allows user to send data. */
DataConnection.prototype.send = function(data) { DataConnection.prototype.send = function(data) {
if (!this.open) {
this.emit('error', new Error('Connection no longer open.'));
}
if (this._reliable) { if (this._reliable) {
// Note: reliable sending will make it so that you cannot customize // Note: reliable sending will make it so that you cannot customize
// serialization. // serialization.
Expand Down Expand Up @@ -1547,7 +1560,9 @@ function ConnectionManager(id, peer, socket, options) {


// Mapping labels to metadata and serialization. // Mapping labels to metadata and serialization.
// label => { metadata: ..., serialization: ..., reliable: ...} // 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. // DataConnections on this PC.
this.connections = {}; this.connections = {};
Expand Down Expand Up @@ -1642,6 +1657,7 @@ ConnectionManager.prototype._setupDataChannel = function() {
// This should not be empty. // This should not be empty.
var options = self.labels[label] || {}; var options = self.labels[label] || {};
var connection = new DataConnection(self.peer, dc, options); var connection = new DataConnection(self.peer, dc, options);
self._attachConnectionListeners(connection);
self.connections[label] = connection; self.connections[label] = connection;
self.emit('connection', connection); self.emit('connection', connection);
}; };
Expand Down Expand Up @@ -1699,7 +1715,33 @@ ConnectionManager.prototype._makeAnswer = function() {
/** Clean up PC, close related DCs. */ /** Clean up PC, close related DCs. */
ConnectionManager.prototype._cleanup = function() { ConnectionManager.prototype._cleanup = function() {
util.log('Cleanup ConnectionManager for ' + this.peer); 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. */ /** Handle an SDP. */
Expand Down Expand Up @@ -1733,25 +1775,31 @@ ConnectionManager.prototype.handleLeave = function() {


/** Closes manager and all related connections. */ /** Closes manager and all related connections. */
ConnectionManager.prototype.close = function() { ConnectionManager.prototype.close = function() {
this._cleanup(); if (!this.open) {
var self = this; this.emit('error', new Error('Connections to ' + this.peer + 'are already closed.'));
if (this.open) { return;
this._socket.send({
type: 'LEAVE',
dst: self.peer
});
} }
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. */ /** Create and returns a DataConnection with the peer with the given label. */
ConnectionManager.prototype.connect = function(label, options) { ConnectionManager.prototype.connect = function(label, options) {
// Check if label is taken. if (!this.open) {
if (!!this.connections[label]) {
this.emit('error', new Error('Label name taken for peer: ' + this.peer));
return; 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({ options = util.extend({
reliable: false, reliable: false,
Expand All @@ -1766,12 +1814,13 @@ ConnectionManager.prototype.connect = function(label, options) {
dc = this.pc.createDataChannel(label, { reliable: false }); dc = this.pc.createDataChannel(label, { reliable: false });
} }
var connection = new DataConnection(this.peer, dc, options); var connection = new DataConnection(this.peer, dc, options);
this._attachConnectionListeners(connection);
this.connections[label] = connection; this.connections[label] = connection;


if (!this.pc) { if (!this.pc) {
this._queued.push(connection); this._queued.push(connection);
} }
return connection; return [label, connection];
}; };


/** Updates label:[serialization, reliable, metadata] pairs from offer. */ /** Updates label:[serialization, reliable, metadata] pairs from offer. */
Expand Down
2 changes: 1 addition & 1 deletion dist/peer.min.js

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions docs/api.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ This event does not need to fire before creating or receiving connections.


`function (error) { }` `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: 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. * `invalid-id`: The ID passed into the Peer constructor contains illegal characters.
Expand All @@ -94,7 +95,7 @@ The `error` object also has a `type` parameter that may be helpful in responding


`function () { }` `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. 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.


Expand Down Expand Up @@ -161,7 +162,7 @@ Emitted when the connection is established and ready for writing. `data` from th


`function (error) { }` `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. `error` is an `Error` object.


Expand Down
64 changes: 50 additions & 14 deletions lib/connectionmanager.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ function ConnectionManager(id, peer, socket, options) {


// Mapping labels to metadata and serialization. // Mapping labels to metadata and serialization.
// label => { metadata: ..., serialization: ..., reliable: ...} // 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. // DataConnections on this PC.
this.connections = {}; this.connections = {};
Expand Down Expand Up @@ -115,6 +117,7 @@ ConnectionManager.prototype._setupDataChannel = function() {
// This should not be empty. // This should not be empty.
var options = self.labels[label] || {}; var options = self.labels[label] || {};
var connection = new DataConnection(self.peer, dc, options); var connection = new DataConnection(self.peer, dc, options);
self._attachConnectionListeners(connection);
self.connections[label] = connection; self.connections[label] = connection;
self.emit('connection', connection); self.emit('connection', connection);
}; };
Expand Down Expand Up @@ -172,7 +175,33 @@ ConnectionManager.prototype._makeAnswer = function() {
/** Clean up PC, close related DCs. */ /** Clean up PC, close related DCs. */
ConnectionManager.prototype._cleanup = function() { ConnectionManager.prototype._cleanup = function() {
util.log('Cleanup ConnectionManager for ' + this.peer); 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. */ /** Handle an SDP. */
Expand Down Expand Up @@ -206,25 +235,31 @@ ConnectionManager.prototype.handleLeave = function() {


/** Closes manager and all related connections. */ /** Closes manager and all related connections. */
ConnectionManager.prototype.close = function() { ConnectionManager.prototype.close = function() {
this._cleanup(); if (!this.open) {
var self = this; this.emit('error', new Error('Connections to ' + this.peer + 'are already closed.'));
if (this.open) { return;
this._socket.send({
type: 'LEAVE',
dst: self.peer
});
} }
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. */ /** Create and returns a DataConnection with the peer with the given label. */
ConnectionManager.prototype.connect = function(label, options) { ConnectionManager.prototype.connect = function(label, options) {
// Check if label is taken. if (!this.open) {
if (!!this.connections[label]) {
this.emit('error', new Error('Label name taken for peer: ' + this.peer));
return; 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({ options = util.extend({
reliable: false, reliable: false,
Expand All @@ -239,12 +274,13 @@ ConnectionManager.prototype.connect = function(label, options) {
dc = this.pc.createDataChannel(label, { reliable: false }); dc = this.pc.createDataChannel(label, { reliable: false });
} }
var connection = new DataConnection(this.peer, dc, options); var connection = new DataConnection(this.peer, dc, options);
this._attachConnectionListeners(connection);
this.connections[label] = connection; this.connections[label] = connection;


if (!this.pc) { if (!this.pc) {
this._queued.push(connection); this._queued.push(connection);
} }
return connection; return [label, connection];
}; };


/** Updates label:[serialization, reliable, metadata] pairs from offer. */ /** Updates label:[serialization, reliable, metadata] pairs from offer. */
Expand Down
15 changes: 11 additions & 4 deletions lib/dataconnection.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ DataConnection.prototype._configureDataChannel = function() {
}; };
} }
this._dc.onclose = function(e) { this._dc.onclose = function(e) {
self.emit('close'); util.log('DataChannel closed.');
self.close();
}; };


// Reliable. // Reliable.
Expand All @@ -58,10 +59,12 @@ DataConnection.prototype._configureDataChannel = function() {
}; };


DataConnection.prototype._cleanup = function() { DataConnection.prototype._cleanup = function() {
if (!!this._dc && this._dc.readyState != 'closed') { if (!!this._dc && this._dc.readyState !== 'closed') {
this._dc.close(); this._dc.close();
this._dc = null; this._dc = null;
} }
this.open = false;
this.emit('close');
}; };


// Handles a DataChannel message. // Handles a DataChannel message.
Expand Down Expand Up @@ -100,13 +103,17 @@ DataConnection.prototype.addDC = function(dc) {


/** Allows user to close connection. */ /** Allows user to close connection. */
DataConnection.prototype.close = function() { DataConnection.prototype.close = function() {
if (!this.open) {
return;
}
this._cleanup(); this._cleanup();
this.open = false;
this.emit('close');
}; };


/** Allows user to send data. */ /** Allows user to send data. */
DataConnection.prototype.send = function(data) { DataConnection.prototype.send = function(data) {
if (!this.open) {
this.emit('error', new Error('Connection no longer open.'));
}
if (this._reliable) { if (this._reliable) {
// Note: reliable sending will make it so that you cannot customize // Note: reliable sending will make it so that you cannot customize
// serialization. // serialization.
Expand Down
Loading

0 comments on commit d62aed6

Please sign in to comment.