Michelle Bu 12 vuotta sitten
vanhempi
commit
32316bbd62
6 muutettua tiedostoa jossa 183 lisäystä ja 156 poistoa
  1. 92 86
      dist/peer.js
  2. 0 0
      dist/peer.min.js
  3. 19 16
      lib/connection.js
  4. 11 10
      lib/peer.js
  5. 58 44
      lib/socket.js
  6. 3 0
      lib/util.js

+ 92 - 86
dist/peer.js

@@ -17,21 +17,6 @@ binaryFeatures.useArrayBufferView = !binaryFeatures.useBlobBuilder && (function(
     return true;
   }
 })();
-binaryFeatures.supportsBinaryWebsockets = (function(){
-  try {
-    var wstest = new WebSocket('ws://null');
-    wstest.onerror = function(){};
-    if (typeof(wstest.binaryType) !== "undefined") {
-      return true;
-    } else {
-      return false;
-    }
-    wstest.close();
-    wstest = null;
-  } catch (e) {
-    return false;
-  }
-})();
 
 exports.binaryFeatures = binaryFeatures;
 exports.BlobBuilder = window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder || window.BlobBuilder;
@@ -604,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;
@@ -817,6 +802,9 @@ var util = {
       byteArray[i] = binary.charCodeAt(i) & 0xff;
     }
     return byteArray.buffer;
+  },
+  randomToken: function () {
+    return Math.random().toString(36).substr(2);
   }
 };
 var RTCPeerConnection = null;
@@ -906,18 +894,19 @@ Peer.prototype._startSocket = function() {
 Peer.prototype._handleServerJSONMessage = function(message) {
   var peer = message.src;
   var connection = this.connections[peer];
+  payload = message.payload;
   switch (message.type) {
     case 'OPEN':
       if (!this.id) {
         // If we're just now getting an ID then we may have a queue.
-        this.id = message.id;
+        this.id = payload.id;
       }
       this.emit('open', this.id);
       this._processQueue();
       break;
     case 'ERROR':
-      this.emit('error', message.msg);
-      util.log(message.msg);
+      this.emit('error', payload.msg);
+      util.log(payload.msg);
       break;
     case 'ID-TAKEN':
       this.emit('error', 'ID `'+this.id+'` is taken');
@@ -925,17 +914,17 @@ Peer.prototype._handleServerJSONMessage = function(message) {
       break;
     case 'OFFER':
       var options = {
-        metadata: message.metadata,
-        sdp: message.sdp,
+        metadata: payload.metadata,
+        sdp: payload.sdp,
         config: this._options.config,
       };
       var connection = new DataConnection(this.id, peer, this._socket, options);
       this._attachConnectionListeners(connection);
       this.connections[peer] = connection;
-      this.emit('connection', connection, message.metadata);
+      this.emit('connection', connection, payload.metadata);
       break;
     case 'EXPIRE':
-      connection = this.connections[message.expired];
+      connection = this.connections[payload.expired];
       if (connection) {
         connection.close();
         connection.emit('Could not connect to peer ' + connection.peer);
@@ -943,12 +932,12 @@ Peer.prototype._handleServerJSONMessage = function(message) {
       break;
     case 'ANSWER':
       if (connection) {
-        connection.handleSDP(message);
+        connection.handleSDP(payload);
       }
       break;
     case 'CANDIDATE':
       if (connection) {
-        connection.handleCandidate(message);
+        connection.handleCandidate(payload);
       }
       break;
     case 'LEAVE':
@@ -962,7 +951,7 @@ Peer.prototype._handleServerJSONMessage = function(message) {
       break;
     case 'PORT':
       //if (util.browserisms === 'Firefox') {
-      //  connection.handlePort(message);
+      //  connection.handlePort(payload);
       //  break;
       //}
     default:
@@ -1142,9 +1131,10 @@ DataConnection.prototype._setupIce = function() {
       util.log('Received ICE candidates');
       self._socket.send({
         type: 'CANDIDATE',
-        candidate: evt.candidate,
-        dst: self.peer,
-        src: self.id
+        payload: {
+          candidate: evt.candidate
+        },
+        dst: self.peer
       });
     }
   };
@@ -1207,10 +1197,11 @@ DataConnection.prototype._makeOffer = function() {
       util.log('Set localDescription to offer');
       self._socket.send({
         type: 'OFFER',
-        sdp: offer,
-        dst: self.peer,
-        src: self.id,
-        metadata: self.metadata
+        payload: {
+          sdp: offer,
+          metadata: self.metadata
+        },
+        dst: self.peer
       });
     }, function(err) {
       self.emit('error', 'Failed to setLocalDescription');
@@ -1228,8 +1219,9 @@ DataConnection.prototype._makeAnswer = function() {
       util.log('Set localDescription to answer');
       self._socket.send({
         type: 'ANSWER',
-        src: self.id,
-        sdp: answer,
+        payload: {
+          sdp: answer
+        },
         dst: self.peer
       });
     }, function(err) {
@@ -1285,8 +1277,7 @@ DataConnection.prototype.close = function() {
   if (this.open) {
     this._socket.send({
       type: 'LEAVE',
-      dst: self.peer,
-      src: self.id,
+      dst: self.peer
     });
   }
   this.open = false;
@@ -1316,16 +1307,17 @@ DataConnection.prototype.handleSDP = function(message) {
   this._pc.setRemoteDescription(sdp, function() {
     util.log('Set remoteDescription: ' + message.type);
     // Firefoxism
-    if (message.type === 'ANSWER' && util.browserisms === 'Firefox') {
+    /**if (message.type === 'ANSWER' && util.browserisms === 'Firefox') {
       self._pc.connectDataConnection(self.localPort, self.remotePort);
       self._socket.send({
         type: 'PORT',
         dst: self.peer,
-        src: self.id,
-        remote: self.localPort,
-        local: self.remotePort
+        payload: {
+          remote: self.localPort,
+          local: self.remotePort
+        }
       });
-    } else if (message.type === 'OFFER') {
+    } else*/ if (message.type === 'OFFER') {
       self._makeAnswer();
     }
   }, function(err) {
@@ -1370,6 +1362,7 @@ function Socket(server, id, key) {
   this._server = server;
   this._httpUrl = 'http://' + this._server;
   this._key = key;
+  this._token = util.randomToken();
 };
 
 util.inherits(Socket, EventEmitter);
@@ -1380,20 +1373,20 @@ Socket.prototype._checkIn = function() {
   var self = this;
   if (!this._id) {
     try {
-      var http = new XMLHttpRequest();
+      this._http = new XMLHttpRequest();
       var url = this._httpUrl;
       // Set API key if necessary.
       if (!!this._key) {
         url += '/' + this._key;
       }
-      url += '/id';
+      url += '/id?token=' + this._token;
 
       // 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 (!self._id && http.readyState > 2 && !!http.responseText) {
+      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(http.responseText.split('\n').shift());
+            var response = JSON.parse(self._http.responseText.split('\n').shift());
             if (!!response.id) {
               self._id = response.id;
               self._startWebSocket();
@@ -1403,9 +1396,10 @@ Socket.prototype._checkIn = function() {
             self._startWebSocket();
           }
         }
-        self._handleStream(http, true);
+        self._handleStream(true);
       };
-      http.send(null);
+      this._http.send(null);
+      this._setHTTPTimeout();
     } catch(e) {
       util.log('XMLHttpRequest not available; defaulting to WebSockets');
       this._startWebSocket();
@@ -1423,15 +1417,15 @@ Socket.prototype._startWebSocket = function() {
     return;
   }
 
-  var wsurl = 'ws://' + this._server + '/ws';
+  var wsurl = 'ws://' + this._server + '/ws?';
+  var query = ['token=' + this._token];
   if (!!this._id) {
-    wsurl += '?id=' + this._id;
-    if (!!this._key) {
-      wsurl += '&key=' + this._key;
-    }
-  } else if (!!this._key) {
-    wsurl += '?key=' + this._key;
+    query.push('id=' + this._id);
+  }
+  if (!!this._key) {
+    query.push('key=' + this._key);
   }
+  wsurl += query.join('&');
   this._socket = new WebSocket(wsurl);
 
   var self = this;
@@ -1452,6 +1446,12 @@ Socket.prototype._startWebSocket = function() {
   // Take care of the queue of connections if necessary and make sure Peer knows
   // socket is open.
   this._socket.onopen = function() {
+    if (!!self._timeout) {
+      clearTimeout(self._timeout);
+      self._http.abort();
+      self._http = null;
+    }
+
     util.log('Socket open');
     if (self._id) {
       self.emit('open');
@@ -1465,19 +1465,21 @@ Socket.prototype._startXhrStream = function() {
   try {
     var self = this;
 
-    var http = new XMLHttpRequest();
+    this._http = new XMLHttpRequest();
     var url = this._httpUrl;
     // Set API key if necessary.
     if (!!this._key) {
       url += '/' + this._key;
     }
     url += '/id';
-    http.open('post', url, true);
-    http.setRequestHeader('Content-Type', 'application/json');
-    http.onreadystatechange = function() {
-      self._handleStream(http);
+    this._http.open('post', url, true);
+    this._http.setRequestHeader('Content-Type', 'application/json');
+    this._http.onreadystatechange = function() {
+      self._handleStream();
     };
-    http.send(JSON.stringify({ id: this._id }));
+    this._http.send(JSON.stringify({ id: this._id, token: this._token }));
+    this._setHTTPTimeout();
+
   } catch(e) {
     util.log('XMLHttpRequest not available; defaulting to WebSockets');
   }
@@ -1485,11 +1487,11 @@ Socket.prototype._startXhrStream = function() {
 
 
 /** Handles onreadystatechange response as a stream. */
-Socket.prototype._handleStream = function(http, pad) {
+Socket.prototype._handleStream = function(pad) {
   // 3 and 4 are loading/done state. All others are not relevant.
-  if (http.readyState < 3) {
+  if (this._http.readyState < 3) {
     return;
-  } else if (http.readyState == 3 && http.status != 200) {
+  } else if (this._http.readyState == 3 && this._http.status != 200) {
     return;
   }
 
@@ -1497,39 +1499,37 @@ Socket.prototype._handleStream = function(http, pad) {
     this._index = pad ? 2 : 1;
   }
   
-  if (http.responseText === null) {
+  if (this._http.responseText === null) {
     return;
   }
   
-  var message = http.responseText.split('\n')[this._index];
-  if (!!message && http.readyState == 3) {
+  var message = this._http.responseText.split('\n')[this._index];
+  if (!!message && this._http.readyState == 3) {
     this._index += 1;
     try {
       this._handleHTTPErrors(JSON.parse(message));
     } catch(e) {
       util.log('Invalid server message', message);
     }
-  } else if (http.readyState == 4) {
+  } else if (this._http.readyState == 4) {
     this._index = 1;
   }
 };
 
+Socket.prototype._setHTTPTimeout = function() {
+  this._timeout = setTimeout(function() {
+    var temp_http = self._http;
+    if (!self._wsOpen()) {
+      self._startXhrStream();
+    }
+    temp_http.abort();
+  }, 30000);
+};
 
 Socket.prototype._handleHTTPErrors = function(message) {
   switch (message.type) {
-    // XHR stream closed by timeout.
-    case 'HTTP-END':
-      util.log('XHR stream timed out.');
-      if (!!this._socket && this._socket.readyState != 1) {
-        this._startXhrStream();
-      }
-      break;
-    // XHR stream closed by socket connect.
-    case 'HTTP-SOCKET':
-      util.log('XHR stream closed, WebSocket connected.');
-      break;
     case 'HTTP-ERROR':
-      util.log('XHR ended in error or the websocket connected first.');
+      util.log('XHR ended in error.');
       break;
     default:
       this.emit('message', message);
@@ -1537,18 +1537,20 @@ Socket.prototype._handleHTTPErrors = function(message) {
 };
 
 
-
 /** Exposed send for DC & Peer. */
 Socket.prototype.send = function(data) {
   var type = data.type;
-  message = JSON.stringify(data);
+  var message;
   if (!type) {
     this.emit('error', 'Invalid message');
   }
 
-  if (!!this._socket && this._socket.readyState == 1) {
+  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;
@@ -1566,11 +1568,15 @@ Socket.prototype.send = function(data) {
 };
 
 Socket.prototype.close = function() {
-  if (!!this._socket && this._socket.readyState == 1) {
+  if (!!this._wsOpen()) {
     this._socket.close();
   }
 };
 
+Socket.prototype._wsOpen = function() {
+  return !!this._socket && this._socket.readyState == 1;
+};
+
 Socket.prototype.start = function() {
   this._checkIn();
 };

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/peer.min.js


+ 19 - 16
lib/connection.js

@@ -110,9 +110,10 @@ DataConnection.prototype._setupIce = function() {
       util.log('Received ICE candidates');
       self._socket.send({
         type: 'CANDIDATE',
-        candidate: evt.candidate,
-        dst: self.peer,
-        src: self.id
+        payload: {
+          candidate: evt.candidate
+        },
+        dst: self.peer
       });
     }
   };
@@ -175,10 +176,11 @@ DataConnection.prototype._makeOffer = function() {
       util.log('Set localDescription to offer');
       self._socket.send({
         type: 'OFFER',
-        sdp: offer,
-        dst: self.peer,
-        src: self.id,
-        metadata: self.metadata
+        payload: {
+          sdp: offer,
+          metadata: self.metadata
+        },
+        dst: self.peer
       });
     }, function(err) {
       self.emit('error', 'Failed to setLocalDescription');
@@ -196,8 +198,9 @@ DataConnection.prototype._makeAnswer = function() {
       util.log('Set localDescription to answer');
       self._socket.send({
         type: 'ANSWER',
-        src: self.id,
-        sdp: answer,
+        payload: {
+          sdp: answer
+        },
         dst: self.peer
       });
     }, function(err) {
@@ -253,8 +256,7 @@ DataConnection.prototype.close = function() {
   if (this.open) {
     this._socket.send({
       type: 'LEAVE',
-      dst: self.peer,
-      src: self.id,
+      dst: self.peer
     });
   }
   this.open = false;
@@ -284,16 +286,17 @@ DataConnection.prototype.handleSDP = function(message) {
   this._pc.setRemoteDescription(sdp, function() {
     util.log('Set remoteDescription: ' + message.type);
     // Firefoxism
-    if (message.type === 'ANSWER' && util.browserisms === 'Firefox') {
+    /**if (message.type === 'ANSWER' && util.browserisms === 'Firefox') {
       self._pc.connectDataConnection(self.localPort, self.remotePort);
       self._socket.send({
         type: 'PORT',
         dst: self.peer,
-        src: self.id,
-        remote: self.localPort,
-        local: self.remotePort
+        payload: {
+          remote: self.localPort,
+          local: self.remotePort
+        }
       });
-    } else if (message.type === 'OFFER') {
+    } else*/ if (message.type === 'OFFER') {
       self._makeAnswer();
     }
   }, function(err) {

+ 11 - 10
lib/peer.js

@@ -67,18 +67,19 @@ Peer.prototype._startSocket = function() {
 Peer.prototype._handleServerJSONMessage = function(message) {
   var peer = message.src;
   var connection = this.connections[peer];
+  payload = message.payload;
   switch (message.type) {
     case 'OPEN':
       if (!this.id) {
         // If we're just now getting an ID then we may have a queue.
-        this.id = message.id;
+        this.id = payload.id;
       }
       this.emit('open', this.id);
       this._processQueue();
       break;
     case 'ERROR':
-      this.emit('error', message.msg);
-      util.log(message.msg);
+      this.emit('error', payload.msg);
+      util.log(payload.msg);
       break;
     case 'ID-TAKEN':
       this.emit('error', 'ID `'+this.id+'` is taken');
@@ -86,17 +87,17 @@ Peer.prototype._handleServerJSONMessage = function(message) {
       break;
     case 'OFFER':
       var options = {
-        metadata: message.metadata,
-        sdp: message.sdp,
+        metadata: payload.metadata,
+        sdp: payload.sdp,
         config: this._options.config,
       };
       var connection = new DataConnection(this.id, peer, this._socket, options);
       this._attachConnectionListeners(connection);
       this.connections[peer] = connection;
-      this.emit('connection', connection, message.metadata);
+      this.emit('connection', connection, payload.metadata);
       break;
     case 'EXPIRE':
-      connection = this.connections[message.expired];
+      connection = this.connections[payload.expired];
       if (connection) {
         connection.close();
         connection.emit('Could not connect to peer ' + connection.peer);
@@ -104,12 +105,12 @@ Peer.prototype._handleServerJSONMessage = function(message) {
       break;
     case 'ANSWER':
       if (connection) {
-        connection.handleSDP(message);
+        connection.handleSDP(payload);
       }
       break;
     case 'CANDIDATE':
       if (connection) {
-        connection.handleCandidate(message);
+        connection.handleCandidate(payload);
       }
       break;
     case 'LEAVE':
@@ -123,7 +124,7 @@ Peer.prototype._handleServerJSONMessage = function(message) {
       break;
     case 'PORT':
       //if (util.browserisms === 'Firefox') {
-      //  connection.handlePort(message);
+      //  connection.handlePort(payload);
       //  break;
       //}
     default:

+ 58 - 44
lib/socket.js

@@ -10,6 +10,7 @@ function Socket(server, id, key) {
   this._server = server;
   this._httpUrl = 'http://' + this._server;
   this._key = key;
+  this._token = util.randomToken();
 };
 
 util.inherits(Socket, EventEmitter);
@@ -20,20 +21,20 @@ Socket.prototype._checkIn = function() {
   var self = this;
   if (!this._id) {
     try {
-      var http = new XMLHttpRequest();
+      this._http = new XMLHttpRequest();
       var url = this._httpUrl;
       // Set API key if necessary.
       if (!!this._key) {
         url += '/' + this._key;
       }
-      url += '/id';
+      url += '/id?token=' + this._token;
 
       // 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 (!self._id && http.readyState > 2 && !!http.responseText) {
+      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(http.responseText.split('\n').shift());
+            var response = JSON.parse(self._http.responseText.split('\n').shift());
             if (!!response.id) {
               self._id = response.id;
               self._startWebSocket();
@@ -43,9 +44,10 @@ Socket.prototype._checkIn = function() {
             self._startWebSocket();
           }
         }
-        self._handleStream(http, true);
+        self._handleStream(true);
       };
-      http.send(null);
+      this._http.send(null);
+      this._setHTTPTimeout();
     } catch(e) {
       util.log('XMLHttpRequest not available; defaulting to WebSockets');
       this._startWebSocket();
@@ -63,15 +65,15 @@ Socket.prototype._startWebSocket = function() {
     return;
   }
 
-  var wsurl = 'ws://' + this._server + '/ws';
+  var wsurl = 'ws://' + this._server + '/ws?';
+  var query = ['token=' + this._token];
   if (!!this._id) {
-    wsurl += '?id=' + this._id;
-    if (!!this._key) {
-      wsurl += '&key=' + this._key;
-    }
-  } else if (!!this._key) {
-    wsurl += '?key=' + this._key;
+    query.push('id=' + this._id);
+  }
+  if (!!this._key) {
+    query.push('key=' + this._key);
   }
+  wsurl += query.join('&');
   this._socket = new WebSocket(wsurl);
 
   var self = this;
@@ -92,6 +94,12 @@ Socket.prototype._startWebSocket = function() {
   // Take care of the queue of connections if necessary and make sure Peer knows
   // socket is open.
   this._socket.onopen = function() {
+    if (!!self._timeout) {
+      clearTimeout(self._timeout);
+      self._http.abort();
+      self._http = null;
+    }
+
     util.log('Socket open');
     if (self._id) {
       self.emit('open');
@@ -105,19 +113,21 @@ Socket.prototype._startXhrStream = function() {
   try {
     var self = this;
 
-    var http = new XMLHttpRequest();
+    this._http = new XMLHttpRequest();
     var url = this._httpUrl;
     // Set API key if necessary.
     if (!!this._key) {
       url += '/' + this._key;
     }
     url += '/id';
-    http.open('post', url, true);
-    http.setRequestHeader('Content-Type', 'application/json');
-    http.onreadystatechange = function() {
-      self._handleStream(http);
+    this._http.open('post', url, true);
+    this._http.setRequestHeader('Content-Type', 'application/json');
+    this._http.onreadystatechange = function() {
+      self._handleStream();
     };
-    http.send(JSON.stringify({ id: this._id }));
+    this._http.send(JSON.stringify({ id: this._id, token: this._token }));
+    this._setHTTPTimeout();
+
   } catch(e) {
     util.log('XMLHttpRequest not available; defaulting to WebSockets');
   }
@@ -125,11 +135,11 @@ Socket.prototype._startXhrStream = function() {
 
 
 /** Handles onreadystatechange response as a stream. */
-Socket.prototype._handleStream = function(http, pad) {
+Socket.prototype._handleStream = function(pad) {
   // 3 and 4 are loading/done state. All others are not relevant.
-  if (http.readyState < 3) {
+  if (this._http.readyState < 3) {
     return;
-  } else if (http.readyState == 3 && http.status != 200) {
+  } else if (this._http.readyState == 3 && this._http.status != 200) {
     return;
   }
 
@@ -137,39 +147,37 @@ Socket.prototype._handleStream = function(http, pad) {
     this._index = pad ? 2 : 1;
   }
   
-  if (http.responseText === null) {
+  if (this._http.responseText === null) {
     return;
   }
   
-  var message = http.responseText.split('\n')[this._index];
-  if (!!message && http.readyState == 3) {
+  var message = this._http.responseText.split('\n')[this._index];
+  if (!!message && this._http.readyState == 3) {
     this._index += 1;
     try {
       this._handleHTTPErrors(JSON.parse(message));
     } catch(e) {
       util.log('Invalid server message', message);
     }
-  } else if (http.readyState == 4) {
+  } else if (this._http.readyState == 4) {
     this._index = 1;
   }
 };
 
+Socket.prototype._setHTTPTimeout = function() {
+  this._timeout = setTimeout(function() {
+    var temp_http = self._http;
+    if (!self._wsOpen()) {
+      self._startXhrStream();
+    }
+    temp_http.abort();
+  }, 30000);
+};
 
 Socket.prototype._handleHTTPErrors = function(message) {
   switch (message.type) {
-    // XHR stream closed by timeout.
-    case 'HTTP-END':
-      util.log('XHR stream timed out.');
-      if (!!this._socket && this._socket.readyState != 1) {
-        this._startXhrStream();
-      }
-      break;
-    // XHR stream closed by socket connect.
-    case 'HTTP-SOCKET':
-      util.log('XHR stream closed, WebSocket connected.');
-      break;
     case 'HTTP-ERROR':
-      util.log('XHR ended in error or the websocket connected first.');
+      util.log('XHR ended in error.');
       break;
     default:
       this.emit('message', message);
@@ -177,18 +185,20 @@ Socket.prototype._handleHTTPErrors = function(message) {
 };
 
 
-
 /** Exposed send for DC & Peer. */
 Socket.prototype.send = function(data) {
   var type = data.type;
-  message = JSON.stringify(data);
+  var message;
   if (!type) {
     this.emit('error', 'Invalid message');
   }
 
-  if (!!this._socket && this._socket.readyState == 1) {
+  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;
@@ -206,11 +216,15 @@ Socket.prototype.send = function(data) {
 };
 
 Socket.prototype.close = function() {
-  if (!!this._socket && this._socket.readyState == 1) {
+  if (!!this._wsOpen()) {
     this._socket.close();
   }
 };
 
+Socket.prototype._wsOpen = function() {
+  return !!this._socket && this._socket.readyState == 1;
+};
+
 Socket.prototype.start = function() {
   this._checkIn();
 };

+ 3 - 0
lib/util.js

@@ -89,5 +89,8 @@ var util = {
       byteArray[i] = binary.charCodeAt(i) & 0xff;
     }
     return byteArray.buffer;
+  },
+  randomToken: function () {
+    return Math.random().toString(36).substr(2);
   }
 };

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä