Jelajahi Sumber

efficiency improvements

ericz 12 tahun lalu
induk
melakukan
8fe0c1ce6e
5 mengubah file dengan 154 tambahan dan 284 penghapusan
  1. 1 1
      deps/EventEmitter
  2. 77 142
      dist/peer.js
  3. 0 0
      dist/peer.min.js
  4. 33 12
      lib/peer.js
  5. 43 129
      lib/socket.js

+ 1 - 1
deps/EventEmitter

@@ -1 +1 @@
-Subproject commit 7e4606d166e1a587263a022b388e1232f42cd7d4
+Subproject commit 5c347bfe5cb8ec62ea2872348ab9304ba0c585f8

+ 77 - 142
dist/peer.js

@@ -589,7 +589,7 @@ EventEmitter.prototype.addListener = function(type, listener, scope, once) {
     // Adding the second element, need to change to array.
     this._events[type] = [this._events[type], listener];
   }
-  return this;
+  
 };
 
 EventEmitter.prototype.on = EventEmitter.prototype.addListener;
@@ -839,14 +839,13 @@ function Peer(id, options) {
   options = util.extend({
     debug: false,
     host: '0.peerjs.com',
-    config: { 'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }] },
-    port: 9000
+    port: 9000,
+    key: 'peerjs',
+    config: { 'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }] }
   }, options);
   this._options = options;
   util.debug = options.debug;
 
-  this._server = options.host + ':' + options.port;
-
   // Ensure alphanumeric_-
   if (id && !/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(id)) {
     throw new Error('Peer ID can only contain alphanumerics, "_", and "-".');
@@ -855,24 +854,46 @@ function Peer(id, options) {
     throw new Error('API key can only contain alphanumerics, "_", and "-".');
   }
 
-  this.id = id;
-  // Not used unless using cloud server.
-  this._key = options.key;
-
-  this._startSocket();
-
   // Connections for this peer.
   this.connections = {};
 
   // Queued connections to make.
   this._queued = [];
+
+  // Init immediately if ID is given, otherwise ask server for ID
+  if (id) {
+    this.id = id;
+    this._init();
+  } else {
+    this._getId();
+  }
 };
 
 util.inherits(Peer, EventEmitter);
 
-Peer.prototype._startSocket = function() {
+Peer.prototype._getId = function(cb) {  
+  var self;
+  try {
+    var http = new XMLHttpRequest();
+    var url = 'http://' + this._options.host + ':' + this._options.port + '/' + this._options.key + '/id';
+    // If there's no ID we need to wait for one before trying to init socket.
+    http.open('get', url, true);
+    http.onreadystatechange = function() {
+      if (http.readyState === 4) {
+        self.id = id;
+        self._init();
+      }
+    };
+    http.send(null);
+  } catch(e) {
+    this.emit('error', 'Could not get an ID from the server');
+  }
+};
+
+
+Peer.prototype._init = function() {
   var self = this;
-  this._socket = new Socket(this._server, this.id, this._key);
+  this._socket = new Socket(this._options.host, this._options.port, this._options.key, this.id);
   this._socket.on('message', function(data) {
     self._handleServerJSONMessage(data);
   });
@@ -1353,93 +1374,48 @@ DataConnection.prototype.handlePort = function(message) {
  * An abstraction on top of WebSockets and XHR streaming to provide fastest
  * possible connection for peers.
  */
-function Socket(server, id, key) {
+function Socket(host, port, key, id) {
   if (!(this instanceof Socket)) return new Socket(server, id, key);
   EventEmitter.call(this);
-
+  
   this._id = id;
-  this._server = server;
-  this._httpUrl = 'http://' + this._server;
-  this._key = key;
-  this._token = util.randomToken();
+  var token = util.randomToken();
+  
+  this._httpUrl = 'http://' + host + ':' + port + '/' + key + '/' + id + '/' + token;
+  this._wsUrl = 'ws://' + this._server + '/ws?key='+key+'id='+id+'token='+token;
+  
+  this._index = 1;
 };
 
 util.inherits(Socket, EventEmitter);
 
+
 /** Check in with ID or get one from server. */
-Socket.prototype._checkIn = function() {
-  // If no ID provided, get a unique ID from server.
-  var self = this;
-  if (!this._id) {
-    try {
-      this._http = new XMLHttpRequest();
-      var url = this._httpUrl;
-      // Set API key if necessary.
-      if (!!this._key) {
-        url += '/' + this._key;
-      }
-      url += '/id?token=' + this._token;
-
-      // If there's no ID we need to wait for one before trying to init socket.
-      this._http.open('get', url, true);
-      this._http.onreadystatechange = function() {
-        if (!self._id && self._http.readyState > 2 && !!self._http.responseText) {
-          try {
-            var response = JSON.parse(self._http.responseText.split('\n').shift());
-            if (!!response.id) {
-              self._id = response.id;
-              self._startWebSocket();
-              self.emit('message', { type: 'OPEN', id: self._id });
-            }
-          } catch (e) {
-            self._startWebSocket();
-          }
-        }
-        self._handleStream(true);
-      };
-      this._http.send(null);
-      this._setHTTPTimeout();
-    } catch(e) {
-      util.log('XMLHttpRequest not available; defaulting to WebSockets');
-      this._startWebSocket();
-    }
-  } else {
-    this._startXhrStream();
-    this._startWebSocket();
-  }
+Socket.prototype.start = function() {  
+  this._startXhrStream();
+  this._startWebSocket();
 };
 
 
 /** Start up websocket communications. */
 Socket.prototype._startWebSocket = function() {
+  var self = this;
+
   if (!!this._socket) {
     return;
   }
 
-  var wsurl = 'ws://' + this._server + '/ws?';
-  var query = ['token=' + this._token];
-  if (!!this._id) {
-    query.push('id=' + this._id);
-  }
-  if (!!this._key) {
-    query.push('key=' + this._key);
-  }
-  wsurl += query.join('&');
   this._socket = new WebSocket(wsurl);
-
-  var self = this;
+  
   this._socket.onmessage = function(event) {
     var data;
     try {
       data = JSON.parse(event.data);
     } catch(e) {
-      data = event.data;
-    }
-    if (data.constructor == Object) {
-      self.emit('message', data);
-    } else {
       util.log('Invalid server message', event.data);
+      return;
     }
+    self.emit('message', data);
   };
 
   // Take care of the queue of connections if necessary and make sure Peer knows
@@ -1450,11 +1426,7 @@ Socket.prototype._startWebSocket = function() {
       self._http.abort();
       self._http = null;
     }
-
     util.log('Socket open');
-    if (self._id) {
-      self.emit('open');
-    }
   };
 };
 
@@ -1463,22 +1435,19 @@ Socket.prototype._startWebSocket = function() {
 Socket.prototype._startXhrStream = function() {
   try {
     var self = this;
-
     this._http = new XMLHttpRequest();
-    var url = this._httpUrl;
-    // Set API key if necessary.
-    if (!!this._key) {
-      url += '/' + this._key;
-    }
-    url += '/id';
-    this._http.open('post', url, true);
-    this._http.setRequestHeader('Content-Type', 'application/json');
+    this._http.open('post', this._httpUrl + '/id', true);
     this._http.onreadystatechange = function() {
-      self._handleStream();
+      if (!!self._http.old) {
+        self._http.old.abort();
+        delete self._http.old;
+      }
+      if (self._http.readyState > 2 && self._http.status == 200 && !!self._http.responseText) {
+        self._handleStream();
+      }
     };
-    this._http.send(JSON.stringify({ id: this._id, token: this._token }));
+    this._http.send(null);
     this._setHTTPTimeout();
-
   } catch(e) {
     util.log('XMLHttpRequest not available; defaulting to WebSockets');
   }
@@ -1486,80 +1455,49 @@ Socket.prototype._startXhrStream = function() {
 
 
 /** Handles onreadystatechange response as a stream. */
-Socket.prototype._handleStream = function(pad) {
+Socket.prototype._handleStream = function() {
+  var self = this;
   // 3 and 4 are loading/done state. All others are not relevant.
-  if (this._http.readyState < 3) {
-    return;
-  } else if (this._http.readyState == 3 && this._http.status != 200) {
-    return;
-  }
-
-  if (this._index === undefined) {
-    this._index = pad ? 2 : 1;
-  }
-  
-  if (this._http.responseText === null) {
-    return;
-  }
-  
   var message = this._http.responseText.split('\n')[this._index];
-  if (!!message && this._http.readyState == 3) {
+  if (!!message) {
     this._index += 1;
     try {
-      this._handleHTTPErrors(JSON.parse(message));
+      message = JSON.parse(message);
     } catch(e) {
       util.log('Invalid server message', message);
+      return;
     }
-  } else if (this._http.readyState == 4) {
-    this._index = 1;
+    self.emit('message', message);
   }
 };
 
 Socket.prototype._setHTTPTimeout = function() {
+  var self = this;
   this._timeout = setTimeout(function() {
-    var temp_http = self._http;
+    var old = self._http;
     if (!self._wsOpen()) {
+      self._index = 1;
       self._startXhrStream();
+      self._http.old = old;        
+    } else {
+      old.abort();
     }
-    temp_http.abort();
   }, 30000);
 };
 
-Socket.prototype._handleHTTPErrors = function(message) {
-  switch (message.type) {
-    case 'HTTP-ERROR':
-      util.log('XHR ended in error.');
-      break;
-    default:
-      this.emit('message', message);
-  }
-};
-
-
 /** Exposed send for DC & Peer. */
 Socket.prototype.send = function(data) {
-  var type = data.type;
-  var message;
-  if (!type) {
+  if (!data.type) {
     this.emit('error', 'Invalid message');
   }
-
+  
+  message = JSON.stringify(data);
+  
   if (this._wsOpen()) {
-    message = JSON.stringify(data);
     this._socket.send(message);
   } else {
-    data['token'] = this._token;
-    message = JSON.stringify(data);
-    var self = this;
     var http = new XMLHttpRequest();
-    var url = this._httpUrl;
-
-    // Set API key if necessary.
-    if (!!this._key) {
-      url += '/' + this._key;
-    }
-    url += '/' + type.toLowerCase();
-
+    var url = this._httpUrl + '/' + type.toLowerCase();
     http.open('post', url, true);
     http.setRequestHeader('Content-Type', 'application/json');
     http.send(message);
@@ -1576,8 +1514,5 @@ Socket.prototype._wsOpen = function() {
   return !!this._socket && this._socket.readyState == 1;
 };
 
-Socket.prototype.start = function() {
-  this._checkIn();
-};
 
 })(this);

File diff ditekan karena terlalu besar
+ 0 - 0
dist/peer.min.js


+ 33 - 12
lib/peer.js

@@ -12,14 +12,13 @@ function Peer(id, options) {
   options = util.extend({
     debug: false,
     host: '0.peerjs.com',
-    config: { 'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }] },
-    port: 9000
+    port: 9000,
+    key: 'peerjs',
+    config: { 'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }] }
   }, options);
   this._options = options;
   util.debug = options.debug;
 
-  this._server = options.host + ':' + options.port;
-
   // Ensure alphanumeric_-
   if (id && !/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(id)) {
     throw new Error('Peer ID can only contain alphanumerics, "_", and "-".');
@@ -28,24 +27,46 @@ function Peer(id, options) {
     throw new Error('API key can only contain alphanumerics, "_", and "-".');
   }
 
-  this.id = id;
-  // Not used unless using cloud server.
-  this._key = options.key;
-
-  this._startSocket();
-
   // Connections for this peer.
   this.connections = {};
 
   // Queued connections to make.
   this._queued = [];
+
+  // Init immediately if ID is given, otherwise ask server for ID
+  if (id) {
+    this.id = id;
+    this._init();
+  } else {
+    this._getId();
+  }
 };
 
 util.inherits(Peer, EventEmitter);
 
-Peer.prototype._startSocket = function() {
+Peer.prototype._getId = function(cb) {  
+  var self;
+  try {
+    var http = new XMLHttpRequest();
+    var url = 'http://' + this._options.host + ':' + this._options.port + '/' + this._options.key + '/id';
+    // If there's no ID we need to wait for one before trying to init socket.
+    http.open('get', url, true);
+    http.onreadystatechange = function() {
+      if (http.readyState === 4) {
+        self.id = id;
+        self._init();
+      }
+    };
+    http.send(null);
+  } catch(e) {
+    this.emit('error', 'Could not get an ID from the server');
+  }
+};
+
+
+Peer.prototype._init = function() {
   var self = this;
-  this._socket = new Socket(this._server, this.id, this._key);
+  this._socket = new Socket(this._options.host, this._options.port, this._options.key, this.id);
   this._socket.on('message', function(data) {
     self._handleServerJSONMessage(data);
   });

+ 43 - 129
lib/socket.js

@@ -2,93 +2,48 @@
  * An abstraction on top of WebSockets and XHR streaming to provide fastest
  * possible connection for peers.
  */
-function Socket(server, id, key) {
+function Socket(host, port, key, id) {
   if (!(this instanceof Socket)) return new Socket(server, id, key);
   EventEmitter.call(this);
-
+  
   this._id = id;
-  this._server = server;
-  this._httpUrl = 'http://' + this._server;
-  this._key = key;
-  this._token = util.randomToken();
+  var token = util.randomToken();
+  
+  this._httpUrl = 'http://' + host + ':' + port + '/' + key + '/' + id + '/' + token;
+  this._wsUrl = 'ws://' + this._server + '/ws?key='+key+'id='+id+'token='+token;
+  
+  this._index = 1;
 };
 
 util.inherits(Socket, EventEmitter);
 
+
 /** Check in with ID or get one from server. */
-Socket.prototype._checkIn = function() {
-  // If no ID provided, get a unique ID from server.
-  var self = this;
-  if (!this._id) {
-    try {
-      this._http = new XMLHttpRequest();
-      var url = this._httpUrl;
-      // Set API key if necessary.
-      if (!!this._key) {
-        url += '/' + this._key;
-      }
-      url += '/id?token=' + this._token;
-
-      // If there's no ID we need to wait for one before trying to init socket.
-      this._http.open('get', url, true);
-      this._http.onreadystatechange = function() {
-        if (!self._id && self._http.readyState > 2 && !!self._http.responseText) {
-          try {
-            var response = JSON.parse(self._http.responseText.split('\n').shift());
-            if (!!response.id) {
-              self._id = response.id;
-              self._startWebSocket();
-              self.emit('message', { type: 'OPEN', id: self._id });
-            }
-          } catch (e) {
-            self._startWebSocket();
-          }
-        }
-        self._handleStream(true);
-      };
-      this._http.send(null);
-      this._setHTTPTimeout();
-    } catch(e) {
-      util.log('XMLHttpRequest not available; defaulting to WebSockets');
-      this._startWebSocket();
-    }
-  } else {
-    this._startXhrStream();
-    this._startWebSocket();
-  }
+Socket.prototype.start = function() {  
+  this._startXhrStream();
+  this._startWebSocket();
 };
 
 
 /** Start up websocket communications. */
 Socket.prototype._startWebSocket = function() {
+  var self = this;
+
   if (!!this._socket) {
     return;
   }
 
-  var wsurl = 'ws://' + this._server + '/ws?';
-  var query = ['token=' + this._token];
-  if (!!this._id) {
-    query.push('id=' + this._id);
-  }
-  if (!!this._key) {
-    query.push('key=' + this._key);
-  }
-  wsurl += query.join('&');
   this._socket = new WebSocket(wsurl);
-
-  var self = this;
+  
   this._socket.onmessage = function(event) {
     var data;
     try {
       data = JSON.parse(event.data);
     } catch(e) {
-      data = event.data;
-    }
-    if (data.constructor == Object) {
-      self.emit('message', data);
-    } else {
       util.log('Invalid server message', event.data);
+      return;
     }
+    self.emit('message', data);
   };
 
   // Take care of the queue of connections if necessary and make sure Peer knows
@@ -99,11 +54,7 @@ Socket.prototype._startWebSocket = function() {
       self._http.abort();
       self._http = null;
     }
-
     util.log('Socket open');
-    if (self._id) {
-      self.emit('open');
-    }
   };
 };
 
@@ -112,22 +63,19 @@ Socket.prototype._startWebSocket = function() {
 Socket.prototype._startXhrStream = function() {
   try {
     var self = this;
-
     this._http = new XMLHttpRequest();
-    var url = this._httpUrl;
-    // Set API key if necessary.
-    if (!!this._key) {
-      url += '/' + this._key;
-    }
-    url += '/id';
-    this._http.open('post', url, true);
-    this._http.setRequestHeader('Content-Type', 'application/json');
+    this._http.open('post', this._httpUrl + '/id', true);
     this._http.onreadystatechange = function() {
-      self._handleStream();
+      if (!!self._http.old) {
+        self._http.old.abort();
+        delete self._http.old;
+      }
+      if (self._http.readyState > 2 && self._http.status == 200 && !!self._http.responseText) {
+        self._handleStream();
+      }
     };
-    this._http.send(JSON.stringify({ id: this._id, token: this._token }));
+    this._http.send(null);
     this._setHTTPTimeout();
-
   } catch(e) {
     util.log('XMLHttpRequest not available; defaulting to WebSockets');
   }
@@ -135,80 +83,49 @@ Socket.prototype._startXhrStream = function() {
 
 
 /** Handles onreadystatechange response as a stream. */
-Socket.prototype._handleStream = function(pad) {
+Socket.prototype._handleStream = function() {
+  var self = this;
   // 3 and 4 are loading/done state. All others are not relevant.
-  if (this._http.readyState < 3) {
-    return;
-  } else if (this._http.readyState == 3 && this._http.status != 200) {
-    return;
-  }
-
-  if (this._index === undefined) {
-    this._index = pad ? 2 : 1;
-  }
-  
-  if (this._http.responseText === null) {
-    return;
-  }
-  
   var message = this._http.responseText.split('\n')[this._index];
-  if (!!message && this._http.readyState == 3) {
+  if (!!message) {
     this._index += 1;
     try {
-      this._handleHTTPErrors(JSON.parse(message));
+      message = JSON.parse(message);
     } catch(e) {
       util.log('Invalid server message', message);
+      return;
     }
-  } else if (this._http.readyState == 4) {
-    this._index = 1;
+    self.emit('message', message);
   }
 };
 
 Socket.prototype._setHTTPTimeout = function() {
+  var self = this;
   this._timeout = setTimeout(function() {
-    var temp_http = self._http;
+    var old = self._http;
     if (!self._wsOpen()) {
+      self._index = 1;
       self._startXhrStream();
+      self._http.old = old;        
+    } else {
+      old.abort();
     }
-    temp_http.abort();
   }, 30000);
 };
 
-Socket.prototype._handleHTTPErrors = function(message) {
-  switch (message.type) {
-    case 'HTTP-ERROR':
-      util.log('XHR ended in error.');
-      break;
-    default:
-      this.emit('message', message);
-  }
-};
-
-
 /** Exposed send for DC & Peer. */
 Socket.prototype.send = function(data) {
-  var type = data.type;
-  var message;
-  if (!type) {
+  if (!data.type) {
     this.emit('error', 'Invalid message');
   }
-
+  
+  message = JSON.stringify(data);
+  
   if (this._wsOpen()) {
-    message = JSON.stringify(data);
     this._socket.send(message);
   } else {
-    data['token'] = this._token;
-    message = JSON.stringify(data);
-    var self = this;
     var http = new XMLHttpRequest();
-    var url = this._httpUrl;
-
-    // Set API key if necessary.
-    if (!!this._key) {
-      url += '/' + this._key;
-    }
-    url += '/' + type.toLowerCase();
-
+    var url = this._httpUrl + '/' + type.toLowerCase();
     http.open('post', url, true);
     http.setRequestHeader('Content-Type', 'application/json');
     http.send(message);
@@ -225,6 +142,3 @@ Socket.prototype._wsOpen = function() {
   return !!this._socket && this._socket.readyState == 1;
 };
 
-Socket.prototype.start = function() {
-  this._checkIn();
-};

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini