mirror of
https://github.com/arnaucube/comunicationLeap.git
synced 2026-02-07 03:16:45 +01:00
nodejs with express server, leapmotion for movement control, and threejs for 3d render
This commit is contained in:
10
node_modules/engine.io-client/lib/index.js
generated
vendored
Normal file
10
node_modules/engine.io-client/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
module.exports = require('./socket');
|
||||
|
||||
/**
|
||||
* Exports parser
|
||||
*
|
||||
* @api public
|
||||
*
|
||||
*/
|
||||
module.exports.parser = require('engine.io-parser');
|
||||
683
node_modules/engine.io-client/lib/socket.js
generated
vendored
Normal file
683
node_modules/engine.io-client/lib/socket.js
generated
vendored
Normal file
@@ -0,0 +1,683 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var transports = require('./transports');
|
||||
var Emitter = require('component-emitter');
|
||||
var debug = require('debug')('engine.io-client:socket');
|
||||
var index = require('indexof');
|
||||
var parser = require('engine.io-parser');
|
||||
var parseuri = require('parseuri');
|
||||
var parsejson = require('parsejson');
|
||||
var parseqs = require('parseqs');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Socket;
|
||||
|
||||
/**
|
||||
* Noop function.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function noop(){}
|
||||
|
||||
/**
|
||||
* Socket constructor.
|
||||
*
|
||||
* @param {String|Object} uri or options
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Socket(uri, opts){
|
||||
if (!(this instanceof Socket)) return new Socket(uri, opts);
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
if (uri && 'object' == typeof uri) {
|
||||
opts = uri;
|
||||
uri = null;
|
||||
}
|
||||
|
||||
if (uri) {
|
||||
uri = parseuri(uri);
|
||||
opts.host = uri.host;
|
||||
opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
|
||||
opts.port = uri.port;
|
||||
if (uri.query) opts.query = uri.query;
|
||||
}
|
||||
|
||||
this.secure = null != opts.secure ? opts.secure :
|
||||
(global.location && 'https:' == location.protocol);
|
||||
|
||||
if (opts.host) {
|
||||
var pieces = opts.host.split(':');
|
||||
opts.hostname = pieces.shift();
|
||||
if (pieces.length) opts.port = pieces.pop();
|
||||
}
|
||||
|
||||
this.agent = opts.agent || false;
|
||||
this.hostname = opts.hostname ||
|
||||
(global.location ? location.hostname : 'localhost');
|
||||
this.port = opts.port || (global.location && location.port ?
|
||||
location.port :
|
||||
(this.secure ? 443 : 80));
|
||||
this.query = opts.query || {};
|
||||
if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
|
||||
this.upgrade = false !== opts.upgrade;
|
||||
this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
|
||||
this.forceJSONP = !!opts.forceJSONP;
|
||||
this.jsonp = false !== opts.jsonp;
|
||||
this.forceBase64 = !!opts.forceBase64;
|
||||
this.enablesXDR = !!opts.enablesXDR;
|
||||
this.timestampParam = opts.timestampParam || 't';
|
||||
this.timestampRequests = opts.timestampRequests;
|
||||
this.transports = opts.transports || ['polling', 'websocket'];
|
||||
this.readyState = '';
|
||||
this.writeBuffer = [];
|
||||
this.callbackBuffer = [];
|
||||
this.policyPort = opts.policyPort || 843;
|
||||
this.rememberUpgrade = opts.rememberUpgrade || false;
|
||||
this.open();
|
||||
this.binaryType = null;
|
||||
this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
|
||||
}
|
||||
|
||||
Socket.priorWebsocketSuccess = false;
|
||||
|
||||
/**
|
||||
* Mix in `Emitter`.
|
||||
*/
|
||||
|
||||
Emitter(Socket.prototype);
|
||||
|
||||
/**
|
||||
* Protocol version.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.protocol = parser.protocol; // this is an int
|
||||
|
||||
/**
|
||||
* Expose deps for legacy compatibility
|
||||
* and standalone browser access.
|
||||
*/
|
||||
|
||||
Socket.Socket = Socket;
|
||||
Socket.Transport = require('./transport');
|
||||
Socket.transports = require('./transports');
|
||||
Socket.parser = require('engine.io-parser');
|
||||
|
||||
/**
|
||||
* Creates transport of the given type.
|
||||
*
|
||||
* @param {String} transport name
|
||||
* @return {Transport}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.createTransport = function (name) {
|
||||
debug('creating transport "%s"', name);
|
||||
var query = clone(this.query);
|
||||
|
||||
// append engine.io protocol identifier
|
||||
query.EIO = parser.protocol;
|
||||
|
||||
// transport name
|
||||
query.transport = name;
|
||||
|
||||
// session id if we already have one
|
||||
if (this.id) query.sid = this.id;
|
||||
|
||||
var transport = new transports[name]({
|
||||
agent: this.agent,
|
||||
hostname: this.hostname,
|
||||
port: this.port,
|
||||
secure: this.secure,
|
||||
path: this.path,
|
||||
query: query,
|
||||
forceJSONP: this.forceJSONP,
|
||||
jsonp: this.jsonp,
|
||||
forceBase64: this.forceBase64,
|
||||
enablesXDR: this.enablesXDR,
|
||||
timestampRequests: this.timestampRequests,
|
||||
timestampParam: this.timestampParam,
|
||||
policyPort: this.policyPort,
|
||||
socket: this
|
||||
});
|
||||
|
||||
return transport;
|
||||
};
|
||||
|
||||
function clone (obj) {
|
||||
var o = {};
|
||||
for (var i in obj) {
|
||||
if (obj.hasOwnProperty(i)) {
|
||||
o[i] = obj[i];
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes transport to use and starts probe.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
Socket.prototype.open = function () {
|
||||
var transport;
|
||||
if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
|
||||
transport = 'websocket';
|
||||
} else if (0 == this.transports.length) {
|
||||
// Emit error on next tick so it can be listened to
|
||||
var self = this;
|
||||
setTimeout(function() {
|
||||
self.emit('error', 'No transports available');
|
||||
}, 0);
|
||||
return;
|
||||
} else {
|
||||
transport = this.transports[0];
|
||||
}
|
||||
this.readyState = 'opening';
|
||||
|
||||
// Retry with the next transport if the transport is disabled (jsonp: false)
|
||||
var transport;
|
||||
try {
|
||||
transport = this.createTransport(transport);
|
||||
} catch (e) {
|
||||
this.transports.shift();
|
||||
this.open();
|
||||
return;
|
||||
}
|
||||
|
||||
transport.open();
|
||||
this.setTransport(transport);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the current transport. Disables the existing one (if any).
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.setTransport = function(transport){
|
||||
debug('setting transport %s', transport.name);
|
||||
var self = this;
|
||||
|
||||
if (this.transport) {
|
||||
debug('clearing existing transport %s', this.transport.name);
|
||||
this.transport.removeAllListeners();
|
||||
}
|
||||
|
||||
// set up transport
|
||||
this.transport = transport;
|
||||
|
||||
// set up transport listeners
|
||||
transport
|
||||
.on('drain', function(){
|
||||
self.onDrain();
|
||||
})
|
||||
.on('packet', function(packet){
|
||||
self.onPacket(packet);
|
||||
})
|
||||
.on('error', function(e){
|
||||
self.onError(e);
|
||||
})
|
||||
.on('close', function(){
|
||||
self.onClose('transport close');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Probes a transport.
|
||||
*
|
||||
* @param {String} transport name
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.probe = function (name) {
|
||||
debug('probing transport "%s"', name);
|
||||
var transport = this.createTransport(name, { probe: 1 })
|
||||
, failed = false
|
||||
, self = this;
|
||||
|
||||
Socket.priorWebsocketSuccess = false;
|
||||
|
||||
function onTransportOpen(){
|
||||
if (self.onlyBinaryUpgrades) {
|
||||
var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
|
||||
failed = failed || upgradeLosesBinary;
|
||||
}
|
||||
if (failed) return;
|
||||
|
||||
debug('probe transport "%s" opened', name);
|
||||
transport.send([{ type: 'ping', data: 'probe' }]);
|
||||
transport.once('packet', function (msg) {
|
||||
if (failed) return;
|
||||
if ('pong' == msg.type && 'probe' == msg.data) {
|
||||
debug('probe transport "%s" pong', name);
|
||||
self.upgrading = true;
|
||||
self.emit('upgrading', transport);
|
||||
if (!transport) return;
|
||||
Socket.priorWebsocketSuccess = 'websocket' == transport.name;
|
||||
|
||||
debug('pausing current transport "%s"', self.transport.name);
|
||||
self.transport.pause(function () {
|
||||
if (failed) return;
|
||||
if ('closed' == self.readyState) return;
|
||||
debug('changing transport and sending upgrade packet');
|
||||
|
||||
cleanup();
|
||||
|
||||
self.setTransport(transport);
|
||||
transport.send([{ type: 'upgrade' }]);
|
||||
self.emit('upgrade', transport);
|
||||
transport = null;
|
||||
self.upgrading = false;
|
||||
self.flush();
|
||||
});
|
||||
} else {
|
||||
debug('probe transport "%s" failed', name);
|
||||
var err = new Error('probe error');
|
||||
err.transport = transport.name;
|
||||
self.emit('upgradeError', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function freezeTransport() {
|
||||
if (failed) return;
|
||||
|
||||
// Any callback called by transport should be ignored since now
|
||||
failed = true;
|
||||
|
||||
cleanup();
|
||||
|
||||
transport.close();
|
||||
transport = null;
|
||||
}
|
||||
|
||||
//Handle any error that happens while probing
|
||||
function onerror(err) {
|
||||
var error = new Error('probe error: ' + err);
|
||||
error.transport = transport.name;
|
||||
|
||||
freezeTransport();
|
||||
|
||||
debug('probe transport "%s" failed because of error: %s', name, err);
|
||||
|
||||
self.emit('upgradeError', error);
|
||||
}
|
||||
|
||||
function onTransportClose(){
|
||||
onerror("transport closed");
|
||||
}
|
||||
|
||||
//When the socket is closed while we're probing
|
||||
function onclose(){
|
||||
onerror("socket closed");
|
||||
}
|
||||
|
||||
//When the socket is upgraded while we're probing
|
||||
function onupgrade(to){
|
||||
if (transport && to.name != transport.name) {
|
||||
debug('"%s" works - aborting "%s"', to.name, transport.name);
|
||||
freezeTransport();
|
||||
}
|
||||
}
|
||||
|
||||
//Remove all listeners on the transport and on self
|
||||
function cleanup(){
|
||||
transport.removeListener('open', onTransportOpen);
|
||||
transport.removeListener('error', onerror);
|
||||
transport.removeListener('close', onTransportClose);
|
||||
self.removeListener('close', onclose);
|
||||
self.removeListener('upgrading', onupgrade);
|
||||
}
|
||||
|
||||
transport.once('open', onTransportOpen);
|
||||
transport.once('error', onerror);
|
||||
transport.once('close', onTransportClose);
|
||||
|
||||
this.once('close', onclose);
|
||||
this.once('upgrading', onupgrade);
|
||||
|
||||
transport.open();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when connection is deemed open.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.onOpen = function () {
|
||||
debug('socket open');
|
||||
this.readyState = 'open';
|
||||
Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
|
||||
this.emit('open');
|
||||
this.flush();
|
||||
|
||||
// we check for `readyState` in case an `open`
|
||||
// listener already closed the socket
|
||||
if ('open' == this.readyState && this.upgrade && this.transport.pause) {
|
||||
debug('starting upgrade probes');
|
||||
for (var i = 0, l = this.upgrades.length; i < l; i++) {
|
||||
this.probe(this.upgrades[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles a packet.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onPacket = function (packet) {
|
||||
if ('opening' == this.readyState || 'open' == this.readyState) {
|
||||
debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
|
||||
|
||||
this.emit('packet', packet);
|
||||
|
||||
// Socket is live - any packet counts
|
||||
this.emit('heartbeat');
|
||||
|
||||
switch (packet.type) {
|
||||
case 'open':
|
||||
this.onHandshake(parsejson(packet.data));
|
||||
break;
|
||||
|
||||
case 'pong':
|
||||
this.setPing();
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
var err = new Error('server error');
|
||||
err.code = packet.data;
|
||||
this.emit('error', err);
|
||||
break;
|
||||
|
||||
case 'message':
|
||||
this.emit('data', packet.data);
|
||||
this.emit('message', packet.data);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
debug('packet received with socket readyState "%s"', this.readyState);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon handshake completion.
|
||||
*
|
||||
* @param {Object} handshake obj
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onHandshake = function (data) {
|
||||
this.emit('handshake', data);
|
||||
this.id = data.sid;
|
||||
this.transport.query.sid = data.sid;
|
||||
this.upgrades = this.filterUpgrades(data.upgrades);
|
||||
this.pingInterval = data.pingInterval;
|
||||
this.pingTimeout = data.pingTimeout;
|
||||
this.onOpen();
|
||||
// In case open handler closes socket
|
||||
if ('closed' == this.readyState) return;
|
||||
this.setPing();
|
||||
|
||||
// Prolong liveness of socket on heartbeat
|
||||
this.removeListener('heartbeat', this.onHeartbeat);
|
||||
this.on('heartbeat', this.onHeartbeat);
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets ping timeout.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onHeartbeat = function (timeout) {
|
||||
clearTimeout(this.pingTimeoutTimer);
|
||||
var self = this;
|
||||
self.pingTimeoutTimer = setTimeout(function () {
|
||||
if ('closed' == self.readyState) return;
|
||||
self.onClose('ping timeout');
|
||||
}, timeout || (self.pingInterval + self.pingTimeout));
|
||||
};
|
||||
|
||||
/**
|
||||
* Pings server every `this.pingInterval` and expects response
|
||||
* within `this.pingTimeout` or closes connection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.setPing = function () {
|
||||
var self = this;
|
||||
clearTimeout(self.pingIntervalTimer);
|
||||
self.pingIntervalTimer = setTimeout(function () {
|
||||
debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
|
||||
self.ping();
|
||||
self.onHeartbeat(self.pingTimeout);
|
||||
}, self.pingInterval);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a ping packet.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.ping = function () {
|
||||
this.sendPacket('ping');
|
||||
};
|
||||
|
||||
/**
|
||||
* Called on `drain` event
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onDrain = function() {
|
||||
for (var i = 0; i < this.prevBufferLen; i++) {
|
||||
if (this.callbackBuffer[i]) {
|
||||
this.callbackBuffer[i]();
|
||||
}
|
||||
}
|
||||
|
||||
this.writeBuffer.splice(0, this.prevBufferLen);
|
||||
this.callbackBuffer.splice(0, this.prevBufferLen);
|
||||
|
||||
// setting prevBufferLen = 0 is very important
|
||||
// for example, when upgrading, upgrade packet is sent over,
|
||||
// and a nonzero prevBufferLen could cause problems on `drain`
|
||||
this.prevBufferLen = 0;
|
||||
|
||||
if (this.writeBuffer.length == 0) {
|
||||
this.emit('drain');
|
||||
} else {
|
||||
this.flush();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Flush write buffers.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.flush = function () {
|
||||
if ('closed' != this.readyState && this.transport.writable &&
|
||||
!this.upgrading && this.writeBuffer.length) {
|
||||
debug('flushing %d packets in socket', this.writeBuffer.length);
|
||||
this.transport.send(this.writeBuffer);
|
||||
// keep track of current length of writeBuffer
|
||||
// splice writeBuffer and callbackBuffer on `drain`
|
||||
this.prevBufferLen = this.writeBuffer.length;
|
||||
this.emit('flush');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a message.
|
||||
*
|
||||
* @param {String} message.
|
||||
* @param {Function} callback function.
|
||||
* @return {Socket} for chaining.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.write =
|
||||
Socket.prototype.send = function (msg, fn) {
|
||||
this.sendPacket('message', msg, fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a packet.
|
||||
*
|
||||
* @param {String} packet type.
|
||||
* @param {String} data.
|
||||
* @param {Function} callback function.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.sendPacket = function (type, data, fn) {
|
||||
if ('closing' == this.readyState || 'closed' == this.readyState) {
|
||||
return;
|
||||
}
|
||||
|
||||
var packet = { type: type, data: data };
|
||||
this.emit('packetCreate', packet);
|
||||
this.writeBuffer.push(packet);
|
||||
this.callbackBuffer.push(fn);
|
||||
this.flush();
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the connection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.close = function () {
|
||||
if ('opening' == this.readyState || 'open' == this.readyState) {
|
||||
this.readyState = 'closing';
|
||||
|
||||
var self = this;
|
||||
|
||||
function close() {
|
||||
self.onClose('forced close');
|
||||
debug('socket closing - telling transport to close');
|
||||
self.transport.close();
|
||||
}
|
||||
|
||||
function cleanupAndClose() {
|
||||
self.removeListener('upgrade', cleanupAndClose);
|
||||
self.removeListener('upgradeError', cleanupAndClose);
|
||||
close();
|
||||
}
|
||||
|
||||
function waitForUpgrade() {
|
||||
// wait for upgrade to finish since we can't send packets while pausing a transport
|
||||
self.once('upgrade', cleanupAndClose);
|
||||
self.once('upgradeError', cleanupAndClose);
|
||||
}
|
||||
|
||||
if (this.writeBuffer.length) {
|
||||
this.once('drain', function() {
|
||||
if (this.upgrading) {
|
||||
waitForUpgrade();
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
});
|
||||
} else if (this.upgrading) {
|
||||
waitForUpgrade();
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon transport error
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onError = function (err) {
|
||||
debug('socket error %j', err);
|
||||
Socket.priorWebsocketSuccess = false;
|
||||
this.emit('error', err);
|
||||
this.onClose('transport error', err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon transport close.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onClose = function (reason, desc) {
|
||||
if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {
|
||||
debug('socket close with reason: "%s"', reason);
|
||||
var self = this;
|
||||
|
||||
// clear timers
|
||||
clearTimeout(this.pingIntervalTimer);
|
||||
clearTimeout(this.pingTimeoutTimer);
|
||||
|
||||
// clean buffers in next tick, so developers can still
|
||||
// grab the buffers on `close` event
|
||||
setTimeout(function() {
|
||||
self.writeBuffer = [];
|
||||
self.callbackBuffer = [];
|
||||
self.prevBufferLen = 0;
|
||||
}, 0);
|
||||
|
||||
// stop event from firing again for transport
|
||||
this.transport.removeAllListeners('close');
|
||||
|
||||
// ensure transport won't stay open
|
||||
this.transport.close();
|
||||
|
||||
// ignore further transport communication
|
||||
this.transport.removeAllListeners();
|
||||
|
||||
// set ready state
|
||||
this.readyState = 'closed';
|
||||
|
||||
// clear session id
|
||||
this.id = null;
|
||||
|
||||
// emit close event
|
||||
this.emit('close', reason, desc);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters upgrades, returning only those matching client transports.
|
||||
*
|
||||
* @param {Array} server upgrades
|
||||
* @api private
|
||||
*
|
||||
*/
|
||||
|
||||
Socket.prototype.filterUpgrades = function (upgrades) {
|
||||
var filteredUpgrades = [];
|
||||
for (var i = 0, j = upgrades.length; i<j; i++) {
|
||||
if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
|
||||
}
|
||||
return filteredUpgrades;
|
||||
};
|
||||
150
node_modules/engine.io-client/lib/transport.js
generated
vendored
Normal file
150
node_modules/engine.io-client/lib/transport.js
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var parser = require('engine.io-parser');
|
||||
var Emitter = require('component-emitter');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Transport;
|
||||
|
||||
/**
|
||||
* Transport abstract constructor.
|
||||
*
|
||||
* @param {Object} options.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Transport (opts) {
|
||||
this.path = opts.path;
|
||||
this.hostname = opts.hostname;
|
||||
this.port = opts.port;
|
||||
this.secure = opts.secure;
|
||||
this.query = opts.query;
|
||||
this.timestampParam = opts.timestampParam;
|
||||
this.timestampRequests = opts.timestampRequests;
|
||||
this.readyState = '';
|
||||
this.agent = opts.agent || false;
|
||||
this.socket = opts.socket;
|
||||
this.enablesXDR = opts.enablesXDR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix in `Emitter`.
|
||||
*/
|
||||
|
||||
Emitter(Transport.prototype);
|
||||
|
||||
/**
|
||||
* A counter used to prevent collisions in the timestamps used
|
||||
* for cache busting.
|
||||
*/
|
||||
|
||||
Transport.timestamps = 0;
|
||||
|
||||
/**
|
||||
* Emits an error.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Transport} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Transport.prototype.onError = function (msg, desc) {
|
||||
var err = new Error(msg);
|
||||
err.type = 'TransportError';
|
||||
err.description = desc;
|
||||
this.emit('error', err);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the transport.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Transport.prototype.open = function () {
|
||||
if ('closed' == this.readyState || '' == this.readyState) {
|
||||
this.readyState = 'opening';
|
||||
this.doOpen();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the transport.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Transport.prototype.close = function () {
|
||||
if ('opening' == this.readyState || 'open' == this.readyState) {
|
||||
this.doClose();
|
||||
this.onClose();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends multiple packets.
|
||||
*
|
||||
* @param {Array} packets
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Transport.prototype.send = function(packets){
|
||||
if ('open' == this.readyState) {
|
||||
this.write(packets);
|
||||
} else {
|
||||
throw new Error('Transport not open');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon open
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Transport.prototype.onOpen = function () {
|
||||
this.readyState = 'open';
|
||||
this.writable = true;
|
||||
this.emit('open');
|
||||
};
|
||||
|
||||
/**
|
||||
* Called with data.
|
||||
*
|
||||
* @param {String} data
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Transport.prototype.onData = function(data){
|
||||
var packet = parser.decodePacket(data, this.socket.binaryType);
|
||||
this.onPacket(packet);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called with a decoded packet.
|
||||
*/
|
||||
|
||||
Transport.prototype.onPacket = function (packet) {
|
||||
this.emit('packet', packet);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon close.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Transport.prototype.onClose = function () {
|
||||
this.readyState = 'closed';
|
||||
this.emit('close');
|
||||
};
|
||||
53
node_modules/engine.io-client/lib/transports/index.js
generated
vendored
Normal file
53
node_modules/engine.io-client/lib/transports/index.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var XMLHttpRequest = require('xmlhttprequest');
|
||||
var XHR = require('./polling-xhr');
|
||||
var JSONP = require('./polling-jsonp');
|
||||
var websocket = require('./websocket');
|
||||
|
||||
/**
|
||||
* Export transports.
|
||||
*/
|
||||
|
||||
exports.polling = polling;
|
||||
exports.websocket = websocket;
|
||||
|
||||
/**
|
||||
* Polling transport polymorphic constructor.
|
||||
* Decides on xhr vs jsonp based on feature detection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function polling(opts){
|
||||
var xhr;
|
||||
var xd = false;
|
||||
var xs = false;
|
||||
var jsonp = false !== opts.jsonp;
|
||||
|
||||
if (global.location) {
|
||||
var isSSL = 'https:' == location.protocol;
|
||||
var port = location.port;
|
||||
|
||||
// some user agents have empty `location.port`
|
||||
if (!port) {
|
||||
port = isSSL ? 443 : 80;
|
||||
}
|
||||
|
||||
xd = opts.hostname != location.hostname || port != opts.port;
|
||||
xs = opts.secure != isSSL;
|
||||
}
|
||||
|
||||
opts.xdomain = xd;
|
||||
opts.xscheme = xs;
|
||||
xhr = new XMLHttpRequest(opts);
|
||||
|
||||
if ('open' in xhr && !opts.forceJSONP) {
|
||||
return new XHR(opts);
|
||||
} else {
|
||||
if (!jsonp) throw new Error('JSONP disabled');
|
||||
return new JSONP(opts);
|
||||
}
|
||||
}
|
||||
233
node_modules/engine.io-client/lib/transports/polling-jsonp.js
generated
vendored
Normal file
233
node_modules/engine.io-client/lib/transports/polling-jsonp.js
generated
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
|
||||
/**
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var Polling = require('./polling');
|
||||
var inherit = require('component-inherit');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = JSONPPolling;
|
||||
|
||||
/**
|
||||
* Cached regular expressions.
|
||||
*/
|
||||
|
||||
var rNewline = /\n/g;
|
||||
var rEscapedNewline = /\\n/g;
|
||||
|
||||
/**
|
||||
* Global JSONP callbacks.
|
||||
*/
|
||||
|
||||
var callbacks;
|
||||
|
||||
/**
|
||||
* Callbacks count.
|
||||
*/
|
||||
|
||||
var index = 0;
|
||||
|
||||
/**
|
||||
* Noop.
|
||||
*/
|
||||
|
||||
function empty () { }
|
||||
|
||||
/**
|
||||
* JSONP Polling constructor.
|
||||
*
|
||||
* @param {Object} opts.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function JSONPPolling (opts) {
|
||||
Polling.call(this, opts);
|
||||
|
||||
this.query = this.query || {};
|
||||
|
||||
// define global callbacks array if not present
|
||||
// we do this here (lazily) to avoid unneeded global pollution
|
||||
if (!callbacks) {
|
||||
// we need to consider multiple engines in the same page
|
||||
if (!global.___eio) global.___eio = [];
|
||||
callbacks = global.___eio;
|
||||
}
|
||||
|
||||
// callback identifier
|
||||
this.index = callbacks.length;
|
||||
|
||||
// add callback to jsonp global
|
||||
var self = this;
|
||||
callbacks.push(function (msg) {
|
||||
self.onData(msg);
|
||||
});
|
||||
|
||||
// append to query string
|
||||
this.query.j = this.index;
|
||||
|
||||
// prevent spurious errors from being emitted when the window is unloaded
|
||||
if (global.document && global.addEventListener) {
|
||||
global.addEventListener('beforeunload', function () {
|
||||
if (self.script) self.script.onerror = empty;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from Polling.
|
||||
*/
|
||||
|
||||
inherit(JSONPPolling, Polling);
|
||||
|
||||
/*
|
||||
* JSONP only supports binary as base64 encoded strings
|
||||
*/
|
||||
|
||||
JSONPPolling.prototype.supportsBinary = false;
|
||||
|
||||
/**
|
||||
* Closes the socket.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
JSONPPolling.prototype.doClose = function () {
|
||||
if (this.script) {
|
||||
this.script.parentNode.removeChild(this.script);
|
||||
this.script = null;
|
||||
}
|
||||
|
||||
if (this.form) {
|
||||
this.form.parentNode.removeChild(this.form);
|
||||
this.form = null;
|
||||
this.iframe = null;
|
||||
}
|
||||
|
||||
Polling.prototype.doClose.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts a poll cycle.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
JSONPPolling.prototype.doPoll = function () {
|
||||
var self = this;
|
||||
var script = document.createElement('script');
|
||||
|
||||
if (this.script) {
|
||||
this.script.parentNode.removeChild(this.script);
|
||||
this.script = null;
|
||||
}
|
||||
|
||||
script.async = true;
|
||||
script.src = this.uri();
|
||||
script.onerror = function(e){
|
||||
self.onError('jsonp poll error',e);
|
||||
};
|
||||
|
||||
var insertAt = document.getElementsByTagName('script')[0];
|
||||
insertAt.parentNode.insertBefore(script, insertAt);
|
||||
this.script = script;
|
||||
|
||||
var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent);
|
||||
|
||||
if (isUAgecko) {
|
||||
setTimeout(function () {
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
document.body.removeChild(iframe);
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes with a hidden iframe.
|
||||
*
|
||||
* @param {String} data to send
|
||||
* @param {Function} called upon flush.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
JSONPPolling.prototype.doWrite = function (data, fn) {
|
||||
var self = this;
|
||||
|
||||
if (!this.form) {
|
||||
var form = document.createElement('form');
|
||||
var area = document.createElement('textarea');
|
||||
var id = this.iframeId = 'eio_iframe_' + this.index;
|
||||
var iframe;
|
||||
|
||||
form.className = 'socketio';
|
||||
form.style.position = 'absolute';
|
||||
form.style.top = '-1000px';
|
||||
form.style.left = '-1000px';
|
||||
form.target = id;
|
||||
form.method = 'POST';
|
||||
form.setAttribute('accept-charset', 'utf-8');
|
||||
area.name = 'd';
|
||||
form.appendChild(area);
|
||||
document.body.appendChild(form);
|
||||
|
||||
this.form = form;
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
this.form.action = this.uri();
|
||||
|
||||
function complete () {
|
||||
initIframe();
|
||||
fn();
|
||||
}
|
||||
|
||||
function initIframe () {
|
||||
if (self.iframe) {
|
||||
try {
|
||||
self.form.removeChild(self.iframe);
|
||||
} catch (e) {
|
||||
self.onError('jsonp polling iframe removal error', e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
|
||||
var html = '<iframe src="javascript:0" name="'+ self.iframeId +'">';
|
||||
iframe = document.createElement(html);
|
||||
} catch (e) {
|
||||
iframe = document.createElement('iframe');
|
||||
iframe.name = self.iframeId;
|
||||
iframe.src = 'javascript:0';
|
||||
}
|
||||
|
||||
iframe.id = self.iframeId;
|
||||
|
||||
self.form.appendChild(iframe);
|
||||
self.iframe = iframe;
|
||||
}
|
||||
|
||||
initIframe();
|
||||
|
||||
// escape \n to prevent it from being converted into \r\n by some UAs
|
||||
// double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
|
||||
data = data.replace(rEscapedNewline, '\\\n');
|
||||
this.area.value = data.replace(rNewline, '\\n');
|
||||
|
||||
try {
|
||||
this.form.submit();
|
||||
} catch(e) {}
|
||||
|
||||
if (this.iframe.attachEvent) {
|
||||
this.iframe.onreadystatechange = function(){
|
||||
if (self.iframe.readyState == 'complete') {
|
||||
complete();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
this.iframe.onload = complete;
|
||||
}
|
||||
};
|
||||
351
node_modules/engine.io-client/lib/transports/polling-xhr.js
generated
vendored
Normal file
351
node_modules/engine.io-client/lib/transports/polling-xhr.js
generated
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
/**
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var XMLHttpRequest = require('xmlhttprequest');
|
||||
var Polling = require('./polling');
|
||||
var Emitter = require('component-emitter');
|
||||
var inherit = require('component-inherit');
|
||||
var debug = require('debug')('engine.io-client:polling-xhr');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = XHR;
|
||||
module.exports.Request = Request;
|
||||
|
||||
/**
|
||||
* Empty function
|
||||
*/
|
||||
|
||||
function empty(){}
|
||||
|
||||
/**
|
||||
* XHR Polling constructor.
|
||||
*
|
||||
* @param {Object} opts
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function XHR(opts){
|
||||
Polling.call(this, opts);
|
||||
|
||||
if (global.location) {
|
||||
var isSSL = 'https:' == location.protocol;
|
||||
var port = location.port;
|
||||
|
||||
// some user agents have empty `location.port`
|
||||
if (!port) {
|
||||
port = isSSL ? 443 : 80;
|
||||
}
|
||||
|
||||
this.xd = opts.hostname != global.location.hostname ||
|
||||
port != opts.port;
|
||||
this.xs = opts.secure != isSSL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from Polling.
|
||||
*/
|
||||
|
||||
inherit(XHR, Polling);
|
||||
|
||||
/**
|
||||
* XHR supports binary
|
||||
*/
|
||||
|
||||
XHR.prototype.supportsBinary = true;
|
||||
|
||||
/**
|
||||
* Creates a request.
|
||||
*
|
||||
* @param {String} method
|
||||
* @api private
|
||||
*/
|
||||
|
||||
XHR.prototype.request = function(opts){
|
||||
opts = opts || {};
|
||||
opts.uri = this.uri();
|
||||
opts.xd = this.xd;
|
||||
opts.xs = this.xs;
|
||||
opts.agent = this.agent || false;
|
||||
opts.supportsBinary = this.supportsBinary;
|
||||
opts.enablesXDR = this.enablesXDR;
|
||||
return new Request(opts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends data.
|
||||
*
|
||||
* @param {String} data to send.
|
||||
* @param {Function} called upon flush.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
XHR.prototype.doWrite = function(data, fn){
|
||||
var isBinary = typeof data !== 'string' && data !== undefined;
|
||||
var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
|
||||
var self = this;
|
||||
req.on('success', fn);
|
||||
req.on('error', function(err){
|
||||
self.onError('xhr post error', err);
|
||||
});
|
||||
this.sendXhr = req;
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts a poll cycle.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
XHR.prototype.doPoll = function(){
|
||||
debug('xhr poll');
|
||||
var req = this.request();
|
||||
var self = this;
|
||||
req.on('data', function(data){
|
||||
self.onData(data);
|
||||
});
|
||||
req.on('error', function(err){
|
||||
self.onError('xhr poll error', err);
|
||||
});
|
||||
this.pollXhr = req;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request constructor
|
||||
*
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Request(opts){
|
||||
this.method = opts.method || 'GET';
|
||||
this.uri = opts.uri;
|
||||
this.xd = !!opts.xd;
|
||||
this.xs = !!opts.xs;
|
||||
this.async = false !== opts.async;
|
||||
this.data = undefined != opts.data ? opts.data : null;
|
||||
this.agent = opts.agent;
|
||||
this.isBinary = opts.isBinary;
|
||||
this.supportsBinary = opts.supportsBinary;
|
||||
this.enablesXDR = opts.enablesXDR;
|
||||
this.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix in `Emitter`.
|
||||
*/
|
||||
|
||||
Emitter(Request.prototype);
|
||||
|
||||
/**
|
||||
* Creates the XHR object and sends the request.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.create = function(){
|
||||
var xhr = this.xhr = new XMLHttpRequest({ agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR });
|
||||
var self = this;
|
||||
|
||||
try {
|
||||
debug('xhr open %s: %s', this.method, this.uri);
|
||||
xhr.open(this.method, this.uri, this.async);
|
||||
if (this.supportsBinary) {
|
||||
// This has to be done after open because Firefox is stupid
|
||||
// http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
|
||||
xhr.responseType = 'arraybuffer';
|
||||
}
|
||||
|
||||
if ('POST' == this.method) {
|
||||
try {
|
||||
if (this.isBinary) {
|
||||
xhr.setRequestHeader('Content-type', 'application/octet-stream');
|
||||
} else {
|
||||
xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// ie6 check
|
||||
if ('withCredentials' in xhr) {
|
||||
xhr.withCredentials = true;
|
||||
}
|
||||
|
||||
if (this.hasXDR()) {
|
||||
xhr.onload = function(){
|
||||
self.onLoad();
|
||||
};
|
||||
xhr.onerror = function(){
|
||||
self.onError(xhr.responseText);
|
||||
};
|
||||
} else {
|
||||
xhr.onreadystatechange = function(){
|
||||
if (4 != xhr.readyState) return;
|
||||
if (200 == xhr.status || 1223 == xhr.status) {
|
||||
self.onLoad();
|
||||
} else {
|
||||
// make sure the `error` event handler that's user-set
|
||||
// does not throw in the same tick and gets caught here
|
||||
setTimeout(function(){
|
||||
self.onError(xhr.status);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
debug('xhr data %s', this.data);
|
||||
xhr.send(this.data);
|
||||
} catch (e) {
|
||||
// Need to defer since .create() is called directly fhrom the constructor
|
||||
// and thus the 'error' event can only be only bound *after* this exception
|
||||
// occurs. Therefore, also, we cannot throw here at all.
|
||||
setTimeout(function() {
|
||||
self.onError(e);
|
||||
}, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (global.document) {
|
||||
this.index = Request.requestsCount++;
|
||||
Request.requests[this.index] = this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon successful response.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.onSuccess = function(){
|
||||
this.emit('success');
|
||||
this.cleanup();
|
||||
};
|
||||
|
||||
/**
|
||||
* Called if we have data.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.onData = function(data){
|
||||
this.emit('data', data);
|
||||
this.onSuccess();
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon error.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.onError = function(err){
|
||||
this.emit('error', err);
|
||||
this.cleanup();
|
||||
};
|
||||
|
||||
/**
|
||||
* Cleans up house.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.cleanup = function(){
|
||||
if ('undefined' == typeof this.xhr || null === this.xhr) {
|
||||
return;
|
||||
}
|
||||
// xmlhttprequest
|
||||
if (this.hasXDR()) {
|
||||
this.xhr.onload = this.xhr.onerror = empty;
|
||||
} else {
|
||||
this.xhr.onreadystatechange = empty;
|
||||
}
|
||||
|
||||
try {
|
||||
this.xhr.abort();
|
||||
} catch(e) {}
|
||||
|
||||
if (global.document) {
|
||||
delete Request.requests[this.index];
|
||||
}
|
||||
|
||||
this.xhr = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon load.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.onLoad = function(){
|
||||
var data;
|
||||
try {
|
||||
var contentType;
|
||||
try {
|
||||
contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];
|
||||
} catch (e) {}
|
||||
if (contentType === 'application/octet-stream') {
|
||||
data = this.xhr.response;
|
||||
} else {
|
||||
if (!this.supportsBinary) {
|
||||
data = this.xhr.responseText;
|
||||
} else {
|
||||
data = 'ok';
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
this.onError(e);
|
||||
}
|
||||
if (null != data) {
|
||||
this.onData(data);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if it has XDomainRequest.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Request.prototype.hasXDR = function(){
|
||||
return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;
|
||||
};
|
||||
|
||||
/**
|
||||
* Aborts the request.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Request.prototype.abort = function(){
|
||||
this.cleanup();
|
||||
};
|
||||
|
||||
/**
|
||||
* Aborts pending requests when unloading the window. This is needed to prevent
|
||||
* memory leaks (e.g. when using IE) and to ensure that no spurious error is
|
||||
* emitted.
|
||||
*/
|
||||
|
||||
if (global.document) {
|
||||
Request.requestsCount = 0;
|
||||
Request.requests = {};
|
||||
if (global.attachEvent) {
|
||||
global.attachEvent('onunload', unloadHandler);
|
||||
} else if (global.addEventListener) {
|
||||
global.addEventListener('beforeunload', unloadHandler);
|
||||
}
|
||||
}
|
||||
|
||||
function unloadHandler() {
|
||||
for (var i in Request.requests) {
|
||||
if (Request.requests.hasOwnProperty(i)) {
|
||||
Request.requests[i].abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
245
node_modules/engine.io-client/lib/transports/polling.js
generated
vendored
Normal file
245
node_modules/engine.io-client/lib/transports/polling.js
generated
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Transport = require('../transport');
|
||||
var parseqs = require('parseqs');
|
||||
var parser = require('engine.io-parser');
|
||||
var inherit = require('component-inherit');
|
||||
var debug = require('debug')('engine.io-client:polling');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Polling;
|
||||
|
||||
/**
|
||||
* Is XHR2 supported?
|
||||
*/
|
||||
|
||||
var hasXHR2 = (function() {
|
||||
var XMLHttpRequest = require('xmlhttprequest');
|
||||
var xhr = new XMLHttpRequest({ xdomain: false });
|
||||
return null != xhr.responseType;
|
||||
})();
|
||||
|
||||
/**
|
||||
* Polling interface.
|
||||
*
|
||||
* @param {Object} opts
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Polling(opts){
|
||||
var forceBase64 = (opts && opts.forceBase64);
|
||||
if (!hasXHR2 || forceBase64) {
|
||||
this.supportsBinary = false;
|
||||
}
|
||||
Transport.call(this, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from Transport.
|
||||
*/
|
||||
|
||||
inherit(Polling, Transport);
|
||||
|
||||
/**
|
||||
* Transport name.
|
||||
*/
|
||||
|
||||
Polling.prototype.name = 'polling';
|
||||
|
||||
/**
|
||||
* Opens the socket (triggers polling). We write a PING message to determine
|
||||
* when the transport is open.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Polling.prototype.doOpen = function(){
|
||||
this.poll();
|
||||
};
|
||||
|
||||
/**
|
||||
* Pauses polling.
|
||||
*
|
||||
* @param {Function} callback upon buffers are flushed and transport is paused
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Polling.prototype.pause = function(onPause){
|
||||
var pending = 0;
|
||||
var self = this;
|
||||
|
||||
this.readyState = 'pausing';
|
||||
|
||||
function pause(){
|
||||
debug('paused');
|
||||
self.readyState = 'paused';
|
||||
onPause();
|
||||
}
|
||||
|
||||
if (this.polling || !this.writable) {
|
||||
var total = 0;
|
||||
|
||||
if (this.polling) {
|
||||
debug('we are currently polling - waiting to pause');
|
||||
total++;
|
||||
this.once('pollComplete', function(){
|
||||
debug('pre-pause polling complete');
|
||||
--total || pause();
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.writable) {
|
||||
debug('we are currently writing - waiting to pause');
|
||||
total++;
|
||||
this.once('drain', function(){
|
||||
debug('pre-pause writing complete');
|
||||
--total || pause();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
pause();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts polling cycle.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Polling.prototype.poll = function(){
|
||||
debug('polling');
|
||||
this.polling = true;
|
||||
this.doPoll();
|
||||
this.emit('poll');
|
||||
};
|
||||
|
||||
/**
|
||||
* Overloads onData to detect payloads.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Polling.prototype.onData = function(data){
|
||||
var self = this;
|
||||
debug('polling got data %s', data);
|
||||
var callback = function(packet, index, total) {
|
||||
// if its the first message we consider the transport open
|
||||
if ('opening' == self.readyState) {
|
||||
self.onOpen();
|
||||
}
|
||||
|
||||
// if its a close packet, we close the ongoing requests
|
||||
if ('close' == packet.type) {
|
||||
self.onClose();
|
||||
return false;
|
||||
}
|
||||
|
||||
// otherwise bypass onData and handle the message
|
||||
self.onPacket(packet);
|
||||
};
|
||||
|
||||
// decode payload
|
||||
parser.decodePayload(data, this.socket.binaryType, callback);
|
||||
|
||||
// if an event did not trigger closing
|
||||
if ('closed' != this.readyState) {
|
||||
// if we got data we're not polling
|
||||
this.polling = false;
|
||||
this.emit('pollComplete');
|
||||
|
||||
if ('open' == this.readyState) {
|
||||
this.poll();
|
||||
} else {
|
||||
debug('ignoring poll - transport state "%s"', this.readyState);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* For polling, send a close packet.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Polling.prototype.doClose = function(){
|
||||
var self = this;
|
||||
|
||||
function close(){
|
||||
debug('writing close packet');
|
||||
self.write([{ type: 'close' }]);
|
||||
}
|
||||
|
||||
if ('open' == this.readyState) {
|
||||
debug('transport open - closing');
|
||||
close();
|
||||
} else {
|
||||
// in case we're trying to close while
|
||||
// handshaking is in progress (GH-164)
|
||||
debug('transport not open - deferring close');
|
||||
this.once('open', close);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes a packets payload.
|
||||
*
|
||||
* @param {Array} data packets
|
||||
* @param {Function} drain callback
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Polling.prototype.write = function(packets){
|
||||
var self = this;
|
||||
this.writable = false;
|
||||
var callbackfn = function() {
|
||||
self.writable = true;
|
||||
self.emit('drain');
|
||||
};
|
||||
|
||||
var self = this;
|
||||
parser.encodePayload(packets, this.supportsBinary, function(data) {
|
||||
self.doWrite(data, callbackfn);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates uri for connection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Polling.prototype.uri = function(){
|
||||
var query = this.query || {};
|
||||
var schema = this.secure ? 'https' : 'http';
|
||||
var port = '';
|
||||
|
||||
// cache busting is forced
|
||||
if (false !== this.timestampRequests) {
|
||||
query[this.timestampParam] = +new Date + '-' + Transport.timestamps++;
|
||||
}
|
||||
|
||||
if (!this.supportsBinary && !query.sid) {
|
||||
query.b64 = 1;
|
||||
}
|
||||
|
||||
query = parseqs.encode(query);
|
||||
|
||||
// avoid port if default for schema
|
||||
if (this.port && (('https' == schema && this.port != 443) ||
|
||||
('http' == schema && this.port != 80))) {
|
||||
port = ':' + this.port;
|
||||
}
|
||||
|
||||
// prepend ? to query
|
||||
if (query.length) {
|
||||
query = '?' + query;
|
||||
}
|
||||
|
||||
return schema + '://' + this.hostname + port + this.path + query;
|
||||
};
|
||||
229
node_modules/engine.io-client/lib/transports/websocket.js
generated
vendored
Normal file
229
node_modules/engine.io-client/lib/transports/websocket.js
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Transport = require('../transport');
|
||||
var parser = require('engine.io-parser');
|
||||
var parseqs = require('parseqs');
|
||||
var inherit = require('component-inherit');
|
||||
var debug = require('debug')('engine.io-client:websocket');
|
||||
|
||||
/**
|
||||
* `ws` exposes a WebSocket-compatible interface in
|
||||
* Node, or the `WebSocket` or `MozWebSocket` globals
|
||||
* in the browser.
|
||||
*/
|
||||
|
||||
var WebSocket = require('ws');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = WS;
|
||||
|
||||
/**
|
||||
* WebSocket transport constructor.
|
||||
*
|
||||
* @api {Object} connection options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function WS(opts){
|
||||
var forceBase64 = (opts && opts.forceBase64);
|
||||
if (forceBase64) {
|
||||
this.supportsBinary = false;
|
||||
}
|
||||
Transport.call(this, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherits from Transport.
|
||||
*/
|
||||
|
||||
inherit(WS, Transport);
|
||||
|
||||
/**
|
||||
* Transport name.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
WS.prototype.name = 'websocket';
|
||||
|
||||
/*
|
||||
* WebSockets support binary
|
||||
*/
|
||||
|
||||
WS.prototype.supportsBinary = true;
|
||||
|
||||
/**
|
||||
* Opens socket.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
WS.prototype.doOpen = function(){
|
||||
if (!this.check()) {
|
||||
// let probe timeout
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var uri = this.uri();
|
||||
var protocols = void(0);
|
||||
var opts = { agent: this.agent };
|
||||
|
||||
this.ws = new WebSocket(uri, protocols, opts);
|
||||
|
||||
if (this.ws.binaryType === undefined) {
|
||||
this.supportsBinary = false;
|
||||
}
|
||||
|
||||
this.ws.binaryType = 'arraybuffer';
|
||||
this.addEventListeners();
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds event listeners to the socket
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
WS.prototype.addEventListeners = function(){
|
||||
var self = this;
|
||||
|
||||
this.ws.onopen = function(){
|
||||
self.onOpen();
|
||||
};
|
||||
this.ws.onclose = function(){
|
||||
self.onClose();
|
||||
};
|
||||
this.ws.onmessage = function(ev){
|
||||
self.onData(ev.data);
|
||||
};
|
||||
this.ws.onerror = function(e){
|
||||
self.onError('websocket error', e);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Override `onData` to use a timer on iOS.
|
||||
* See: https://gist.github.com/mloughran/2052006
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
if ('undefined' != typeof navigator
|
||||
&& /iPad|iPhone|iPod/i.test(navigator.userAgent)) {
|
||||
WS.prototype.onData = function(data){
|
||||
var self = this;
|
||||
setTimeout(function(){
|
||||
Transport.prototype.onData.call(self, data);
|
||||
}, 0);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data to socket.
|
||||
*
|
||||
* @param {Array} array of packets.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
WS.prototype.write = function(packets){
|
||||
var self = this;
|
||||
this.writable = false;
|
||||
// encodePacket efficient as it uses WS framing
|
||||
// no need for encodePayload
|
||||
for (var i = 0, l = packets.length; i < l; i++) {
|
||||
parser.encodePacket(packets[i], this.supportsBinary, function(data) {
|
||||
//Sometimes the websocket has already been closed but the browser didn't
|
||||
//have a chance of informing us about it yet, in that case send will
|
||||
//throw an error
|
||||
try {
|
||||
self.ws.send(data);
|
||||
} catch (e){
|
||||
debug('websocket closed before onclose event');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ondrain() {
|
||||
self.writable = true;
|
||||
self.emit('drain');
|
||||
}
|
||||
// fake drain
|
||||
// defer to next tick to allow Socket to clear writeBuffer
|
||||
setTimeout(ondrain, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon close
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
WS.prototype.onClose = function(){
|
||||
Transport.prototype.onClose.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes socket.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
WS.prototype.doClose = function(){
|
||||
if (typeof this.ws !== 'undefined') {
|
||||
this.ws.close();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates uri for connection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
WS.prototype.uri = function(){
|
||||
var query = this.query || {};
|
||||
var schema = this.secure ? 'wss' : 'ws';
|
||||
var port = '';
|
||||
|
||||
// avoid port if default for schema
|
||||
if (this.port && (('wss' == schema && this.port != 443)
|
||||
|| ('ws' == schema && this.port != 80))) {
|
||||
port = ':' + this.port;
|
||||
}
|
||||
|
||||
// append timestamp to URI
|
||||
if (this.timestampRequests) {
|
||||
query[this.timestampParam] = +new Date;
|
||||
}
|
||||
|
||||
// communicate binary support capabilities
|
||||
if (!this.supportsBinary) {
|
||||
query.b64 = 1;
|
||||
}
|
||||
|
||||
query = parseqs.encode(query);
|
||||
|
||||
// prepend ? to query
|
||||
if (query.length) {
|
||||
query = '?' + query;
|
||||
}
|
||||
|
||||
return schema + '://' + this.hostname + port + this.path + query;
|
||||
};
|
||||
|
||||
/**
|
||||
* Feature detection for WebSocket.
|
||||
*
|
||||
* @return {Boolean} whether this transport is available.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
WS.prototype.check = function(){
|
||||
return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);
|
||||
};
|
||||
36
node_modules/engine.io-client/lib/xmlhttprequest.js
generated
vendored
Normal file
36
node_modules/engine.io-client/lib/xmlhttprequest.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// browser shim for xmlhttprequest module
|
||||
var hasCORS = require('has-cors');
|
||||
|
||||
module.exports = function(opts) {
|
||||
var xdomain = opts.xdomain;
|
||||
|
||||
// scheme must be same when usign XDomainRequest
|
||||
// http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
|
||||
var xscheme = opts.xscheme;
|
||||
|
||||
// XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
|
||||
// https://github.com/Automattic/engine.io-client/pull/217
|
||||
var enablesXDR = opts.enablesXDR;
|
||||
|
||||
// XMLHttpRequest can be disabled on IE
|
||||
try {
|
||||
if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {
|
||||
return new XMLHttpRequest();
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
// Use XDomainRequest for IE8 if enablesXDR is true
|
||||
// because loading bar keeps flashing when using jsonp-polling
|
||||
// https://github.com/yujiosaka/socke.io-ie8-loading-example
|
||||
try {
|
||||
if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {
|
||||
return new XDomainRequest();
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
if (!xdomain) {
|
||||
try {
|
||||
return new ActiveXObject('Microsoft.XMLHTTP');
|
||||
} catch(e) { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user