|
@@ -75,7 +75,7 @@ function Peer(id, options) {
|
|
|
|
|
|
// States.
|
|
// States.
|
|
this.destroyed = false; // Connections have been killed
|
|
this.destroyed = false; // Connections have been killed
|
|
- this.disconnected = false; // Connection to PeerServer killed manually but P2P connections still active
|
|
|
|
|
|
+ this.disconnected = false; // Connection to PeerServer killed but P2P connections still active
|
|
this.open = false; // Sockets and such are not yet open.
|
|
this.open = false; // Sockets and such are not yet open.
|
|
//
|
|
//
|
|
|
|
|
|
@@ -84,8 +84,21 @@ function Peer(id, options) {
|
|
this._lostMessages = {}; // src => [list of messages]
|
|
this._lostMessages = {}; // src => [list of messages]
|
|
//
|
|
//
|
|
|
|
|
|
- // Initialize the 'socket' (which is actually a mix of XHR streaming and
|
|
|
|
- // websockets.)
|
|
|
|
|
|
+ // Start the server connection
|
|
|
|
+ this._initializeServerConnection();
|
|
|
|
+ if (id) {
|
|
|
|
+ this._initialize(id);
|
|
|
|
+ } else {
|
|
|
|
+ this._retrieveId();
|
|
|
|
+ }
|
|
|
|
+ //
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+util.inherits(Peer, EventEmitter);
|
|
|
|
+
|
|
|
|
+// Initialize the 'socket' (which is actually a mix of XHR streaming and
|
|
|
|
+// websockets.)
|
|
|
|
+Peer.prototype._initializeServerConnection = function() {
|
|
var self = this;
|
|
var self = this;
|
|
this.socket = new Socket(this.options.secure, this.options.host, this.options.port, this.options.path, this.options.key);
|
|
this.socket = new Socket(this.options.secure, this.options.host, this.options.port, this.options.path, this.options.key);
|
|
this.socket.on('message', function(data) {
|
|
this.socket.on('message', function(data) {
|
|
@@ -99,19 +112,22 @@ function Peer(id, options) {
|
|
self._abort('socket-closed', 'Underlying socket is already closed.');
|
|
self._abort('socket-closed', 'Underlying socket is already closed.');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
- //
|
|
|
|
|
|
+};
|
|
|
|
|
|
- // Start the connections
|
|
|
|
- if (id) {
|
|
|
|
- this._initialize(id);
|
|
|
|
|
|
+Peer.prototype.reconnect = function() {
|
|
|
|
+ if (this.disconnected && !this.destroyed) {
|
|
|
|
+ this._initializeServerConnection();
|
|
|
|
+ this._initialize(this._lastServerId);
|
|
|
|
+ } else if (this.destroyed) {
|
|
|
|
+ throw new Error('This peer cannot reconnect to the server. It has already been destroyed.');
|
|
|
|
+ } else if (!this.disconnected && !this.open) {
|
|
|
|
+ // Do nothing. We're still connecting the first time.
|
|
|
|
+ util.error('In a hurry? We\'re still trying to make the initial connection!');
|
|
} else {
|
|
} else {
|
|
- this._retrieveId();
|
|
|
|
|
|
+ throw new Error('Peer ' + this.id + ' cannot reconnect because it is not disconnected from the server!');
|
|
}
|
|
}
|
|
- //
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-util.inherits(Peer, EventEmitter);
|
|
|
|
-
|
|
|
|
/** Get a unique ID from the server via XHR. */
|
|
/** Get a unique ID from the server via XHR. */
|
|
Peer.prototype._retrieveId = function(cb) {
|
|
Peer.prototype._retrieveId = function(cb) {
|
|
var self = this;
|
|
var self = this;
|
|
@@ -149,7 +165,6 @@ Peer.prototype._retrieveId = function(cb) {
|
|
|
|
|
|
/** Initialize a connection with the server. */
|
|
/** Initialize a connection with the server. */
|
|
Peer.prototype._initialize = function(id) {
|
|
Peer.prototype._initialize = function(id) {
|
|
- var self = this;
|
|
|
|
this.id = id;
|
|
this.id = id;
|
|
this.socket.start(this.id, this.options.token);
|
|
this.socket.start(this.id, this.options.token);
|
|
}
|
|
}
|
|
@@ -182,7 +197,7 @@ Peer.prototype._handleMessage = function(message) {
|
|
break;
|
|
break;
|
|
|
|
|
|
case 'EXPIRE': // The offer sent to a peer has expired without response.
|
|
case 'EXPIRE': // The offer sent to a peer has expired without response.
|
|
- this.emit('error', new Error('Could not connect to peer ' + peer));
|
|
|
|
|
|
+ this.emitError('peer-unavailable', 'Could not connect to peer ' + peer);
|
|
break;
|
|
break;
|
|
case 'OFFER': // we should consider switching this to CALL/CONNECT, but this is the least breaking option.
|
|
case 'OFFER': // we should consider switching this to CALL/CONNECT, but this is the least breaking option.
|
|
var connectionId = payload.connectionId;
|
|
var connectionId = payload.connectionId;
|
|
@@ -273,7 +288,7 @@ Peer.prototype.connect = function(peer, options) {
|
|
util.warn('You cannot connect to a new Peer because you called '
|
|
util.warn('You cannot connect to a new Peer because you called '
|
|
+ '.disconnect() on this Peer and ended your connection with the'
|
|
+ '.disconnect() on this Peer and ended your connection with the'
|
|
+ ' server. You can create a new Peer to reconnect.');
|
|
+ ' server. You can create a new Peer to reconnect.');
|
|
- this.emit('error', new Error('Cannot connect to new Peer after disconnecting from server.'));
|
|
|
|
|
|
+ this.emitError('disconnected', 'Cannot connect to new Peer after disconnecting from server.');
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
var connection = new DataConnection(peer, this, options);
|
|
var connection = new DataConnection(peer, this, options);
|
|
@@ -290,7 +305,7 @@ Peer.prototype.call = function(peer, stream, options) {
|
|
util.warn('You cannot connect to a new Peer because you called '
|
|
util.warn('You cannot connect to a new Peer because you called '
|
|
+ '.disconnect() on this Peer and ended your connection with the'
|
|
+ '.disconnect() on this Peer and ended your connection with the'
|
|
+ ' server. You can create a new Peer to reconnect.');
|
|
+ ' server. You can create a new Peer to reconnect.');
|
|
- this.emit('error', new Error('Cannot connect to new Peer after disconnecting from server.'));
|
|
|
|
|
|
+ this.emitError('disconnected', 'Cannot connect to new Peer after disconnecting from server.');
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
if (!stream) {
|
|
if (!stream) {
|
|
@@ -335,10 +350,17 @@ Peer.prototype._delayedAbort = function(type, message) {
|
|
|
|
|
|
/** Destroys the Peer and emits an error message. */
|
|
/** Destroys the Peer and emits an error message. */
|
|
Peer.prototype._abort = function(type, message) {
|
|
Peer.prototype._abort = function(type, message) {
|
|
- util.error('Aborting. Error:', message);
|
|
|
|
- var err = new Error(message);
|
|
|
|
|
|
+ util.error('Aborting!');
|
|
|
|
+ this.emitError(type, message);
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/** Emits a typed error message. */
|
|
|
|
+Peer.prototype.emitError = function(type, err) {
|
|
|
|
+ util.error('Error:', err);
|
|
|
|
+ if (typeof err === 'string') {
|
|
|
|
+ err = new Error(err);
|
|
|
|
+ }
|
|
err.type = type;
|
|
err.type = type;
|
|
- this.destroy();
|
|
|
|
this.emit('error', err);
|
|
this.emit('error', err);
|
|
};
|
|
};
|
|
|
|
|
|
@@ -391,6 +413,8 @@ Peer.prototype.disconnect = function() {
|
|
if (self.socket) {
|
|
if (self.socket) {
|
|
self.socket.close();
|
|
self.socket.close();
|
|
}
|
|
}
|
|
|
|
+ self.emit('disconnected', self.id);
|
|
|
|
+ self._lastServerId = self.id;
|
|
self.id = null;
|
|
self.id = null;
|
|
}
|
|
}
|
|
});
|
|
});
|