Simulator first commit
This commit is contained in:
94
node_modules/socket.io-client/lib/index.js
generated
vendored
Normal file
94
node_modules/socket.io-client/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var url = require('./url');
|
||||
var parser = require('socket.io-parser');
|
||||
var Manager = require('./manager');
|
||||
var debug = require('debug')('socket.io-client');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = lookup;
|
||||
|
||||
/**
|
||||
* Managers cache.
|
||||
*/
|
||||
|
||||
var cache = exports.managers = {};
|
||||
|
||||
/**
|
||||
* Looks up an existing `Manager` for multiplexing.
|
||||
* If the user summons:
|
||||
*
|
||||
* `io('http://localhost/a');`
|
||||
* `io('http://localhost/b');`
|
||||
*
|
||||
* We reuse the existing instance based on same scheme/port/host,
|
||||
* and we initialize sockets for each namespace.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function lookup (uri, opts) {
|
||||
if (typeof uri === 'object') {
|
||||
opts = uri;
|
||||
uri = undefined;
|
||||
}
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
var parsed = url(uri);
|
||||
var source = parsed.source;
|
||||
var id = parsed.id;
|
||||
var path = parsed.path;
|
||||
var sameNamespace = cache[id] && path in cache[id].nsps;
|
||||
var newConnection = opts.forceNew || opts['force new connection'] ||
|
||||
false === opts.multiplex || sameNamespace;
|
||||
|
||||
var io;
|
||||
|
||||
if (newConnection) {
|
||||
debug('ignoring socket cache for %s', source);
|
||||
io = Manager(source, opts);
|
||||
} else {
|
||||
if (!cache[id]) {
|
||||
debug('new io instance for %s', source);
|
||||
cache[id] = Manager(source, opts);
|
||||
}
|
||||
io = cache[id];
|
||||
}
|
||||
if (parsed.query && !opts.query) {
|
||||
opts.query = parsed.query;
|
||||
}
|
||||
return io.socket(parsed.path, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Protocol version.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.protocol = parser.protocol;
|
||||
|
||||
/**
|
||||
* `connect`.
|
||||
*
|
||||
* @param {String} uri
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.connect = lookup;
|
||||
|
||||
/**
|
||||
* Expose constructors for standalone build.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.Manager = require('./manager');
|
||||
exports.Socket = require('./socket');
|
573
node_modules/socket.io-client/lib/manager.js
generated
vendored
Normal file
573
node_modules/socket.io-client/lib/manager.js
generated
vendored
Normal file
@ -0,0 +1,573 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var eio = require('engine.io-client');
|
||||
var Socket = require('./socket');
|
||||
var Emitter = require('component-emitter');
|
||||
var parser = require('socket.io-parser');
|
||||
var on = require('./on');
|
||||
var bind = require('component-bind');
|
||||
var debug = require('debug')('socket.io-client:manager');
|
||||
var indexOf = require('indexof');
|
||||
var Backoff = require('backo2');
|
||||
|
||||
/**
|
||||
* IE6+ hasOwnProperty
|
||||
*/
|
||||
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = Manager;
|
||||
|
||||
/**
|
||||
* `Manager` constructor.
|
||||
*
|
||||
* @param {String} engine instance or engine uri/opts
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Manager (uri, opts) {
|
||||
if (!(this instanceof Manager)) return new Manager(uri, opts);
|
||||
if (uri && ('object' === typeof uri)) {
|
||||
opts = uri;
|
||||
uri = undefined;
|
||||
}
|
||||
opts = opts || {};
|
||||
|
||||
opts.path = opts.path || '/socket.io';
|
||||
this.nsps = {};
|
||||
this.subs = [];
|
||||
this.opts = opts;
|
||||
this.reconnection(opts.reconnection !== false);
|
||||
this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
|
||||
this.reconnectionDelay(opts.reconnectionDelay || 1000);
|
||||
this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
|
||||
this.randomizationFactor(opts.randomizationFactor || 0.5);
|
||||
this.backoff = new Backoff({
|
||||
min: this.reconnectionDelay(),
|
||||
max: this.reconnectionDelayMax(),
|
||||
jitter: this.randomizationFactor()
|
||||
});
|
||||
this.timeout(null == opts.timeout ? 20000 : opts.timeout);
|
||||
this.readyState = 'closed';
|
||||
this.uri = uri;
|
||||
this.connecting = [];
|
||||
this.lastPing = null;
|
||||
this.encoding = false;
|
||||
this.packetBuffer = [];
|
||||
var _parser = opts.parser || parser;
|
||||
this.encoder = new _parser.Encoder();
|
||||
this.decoder = new _parser.Decoder();
|
||||
this.autoConnect = opts.autoConnect !== false;
|
||||
if (this.autoConnect) this.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate given event to sockets and emit on `this`
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.emitAll = function () {
|
||||
this.emit.apply(this, arguments);
|
||||
for (var nsp in this.nsps) {
|
||||
if (has.call(this.nsps, nsp)) {
|
||||
this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update `socket.id` of all sockets
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.updateSocketIds = function () {
|
||||
for (var nsp in this.nsps) {
|
||||
if (has.call(this.nsps, nsp)) {
|
||||
this.nsps[nsp].id = this.generateId(nsp);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* generate `socket.id` for the given `nsp`
|
||||
*
|
||||
* @param {String} nsp
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.generateId = function (nsp) {
|
||||
return (nsp === '/' ? '' : (nsp + '#')) + this.engine.id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mix in `Emitter`.
|
||||
*/
|
||||
|
||||
Emitter(Manager.prototype);
|
||||
|
||||
/**
|
||||
* Sets the `reconnection` config.
|
||||
*
|
||||
* @param {Boolean} true/false if it should automatically reconnect
|
||||
* @return {Manager} self or value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.reconnection = function (v) {
|
||||
if (!arguments.length) return this._reconnection;
|
||||
this._reconnection = !!v;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the reconnection attempts config.
|
||||
*
|
||||
* @param {Number} max reconnection attempts before giving up
|
||||
* @return {Manager} self or value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.reconnectionAttempts = function (v) {
|
||||
if (!arguments.length) return this._reconnectionAttempts;
|
||||
this._reconnectionAttempts = v;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the delay between reconnections.
|
||||
*
|
||||
* @param {Number} delay
|
||||
* @return {Manager} self or value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.reconnectionDelay = function (v) {
|
||||
if (!arguments.length) return this._reconnectionDelay;
|
||||
this._reconnectionDelay = v;
|
||||
this.backoff && this.backoff.setMin(v);
|
||||
return this;
|
||||
};
|
||||
|
||||
Manager.prototype.randomizationFactor = function (v) {
|
||||
if (!arguments.length) return this._randomizationFactor;
|
||||
this._randomizationFactor = v;
|
||||
this.backoff && this.backoff.setJitter(v);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the maximum delay between reconnections.
|
||||
*
|
||||
* @param {Number} delay
|
||||
* @return {Manager} self or value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.reconnectionDelayMax = function (v) {
|
||||
if (!arguments.length) return this._reconnectionDelayMax;
|
||||
this._reconnectionDelayMax = v;
|
||||
this.backoff && this.backoff.setMax(v);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the connection timeout. `false` to disable
|
||||
*
|
||||
* @return {Manager} self or value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.timeout = function (v) {
|
||||
if (!arguments.length) return this._timeout;
|
||||
this._timeout = v;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Starts trying to reconnect if reconnection is enabled and we have not
|
||||
* started reconnecting yet
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.maybeReconnectOnOpen = function () {
|
||||
// Only try to reconnect if it's the first time we're connecting
|
||||
if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {
|
||||
// keeps reconnection from firing twice for the same reconnection loop
|
||||
this.reconnect();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the current transport `socket`.
|
||||
*
|
||||
* @param {Function} optional, callback
|
||||
* @return {Manager} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.open =
|
||||
Manager.prototype.connect = function (fn, opts) {
|
||||
debug('readyState %s', this.readyState);
|
||||
if (~this.readyState.indexOf('open')) return this;
|
||||
|
||||
debug('opening %s', this.uri);
|
||||
this.engine = eio(this.uri, this.opts);
|
||||
var socket = this.engine;
|
||||
var self = this;
|
||||
this.readyState = 'opening';
|
||||
this.skipReconnect = false;
|
||||
|
||||
// emit `open`
|
||||
var openSub = on(socket, 'open', function () {
|
||||
self.onopen();
|
||||
fn && fn();
|
||||
});
|
||||
|
||||
// emit `connect_error`
|
||||
var errorSub = on(socket, 'error', function (data) {
|
||||
debug('connect_error');
|
||||
self.cleanup();
|
||||
self.readyState = 'closed';
|
||||
self.emitAll('connect_error', data);
|
||||
if (fn) {
|
||||
var err = new Error('Connection error');
|
||||
err.data = data;
|
||||
fn(err);
|
||||
} else {
|
||||
// Only do this if there is no fn to handle the error
|
||||
self.maybeReconnectOnOpen();
|
||||
}
|
||||
});
|
||||
|
||||
// emit `connect_timeout`
|
||||
if (false !== this._timeout) {
|
||||
var timeout = this._timeout;
|
||||
debug('connect attempt will timeout after %d', timeout);
|
||||
|
||||
// set timer
|
||||
var timer = setTimeout(function () {
|
||||
debug('connect attempt timed out after %d', timeout);
|
||||
openSub.destroy();
|
||||
socket.close();
|
||||
socket.emit('error', 'timeout');
|
||||
self.emitAll('connect_timeout', timeout);
|
||||
}, timeout);
|
||||
|
||||
this.subs.push({
|
||||
destroy: function () {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.subs.push(openSub);
|
||||
this.subs.push(errorSub);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon transport open.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.onopen = function () {
|
||||
debug('open');
|
||||
|
||||
// clear old subs
|
||||
this.cleanup();
|
||||
|
||||
// mark as open
|
||||
this.readyState = 'open';
|
||||
this.emit('open');
|
||||
|
||||
// add new subs
|
||||
var socket = this.engine;
|
||||
this.subs.push(on(socket, 'data', bind(this, 'ondata')));
|
||||
this.subs.push(on(socket, 'ping', bind(this, 'onping')));
|
||||
this.subs.push(on(socket, 'pong', bind(this, 'onpong')));
|
||||
this.subs.push(on(socket, 'error', bind(this, 'onerror')));
|
||||
this.subs.push(on(socket, 'close', bind(this, 'onclose')));
|
||||
this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon a ping.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.onping = function () {
|
||||
this.lastPing = new Date();
|
||||
this.emitAll('ping');
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon a packet.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.onpong = function () {
|
||||
this.emitAll('pong', new Date() - this.lastPing);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called with data.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.ondata = function (data) {
|
||||
this.decoder.add(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when parser fully decodes a packet.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.ondecoded = function (packet) {
|
||||
this.emit('packet', packet);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon socket error.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.onerror = function (err) {
|
||||
debug('error', err);
|
||||
this.emitAll('error', err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new socket for the given `nsp`.
|
||||
*
|
||||
* @return {Socket}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Manager.prototype.socket = function (nsp, opts) {
|
||||
var socket = this.nsps[nsp];
|
||||
if (!socket) {
|
||||
socket = new Socket(this, nsp, opts);
|
||||
this.nsps[nsp] = socket;
|
||||
var self = this;
|
||||
socket.on('connecting', onConnecting);
|
||||
socket.on('connect', function () {
|
||||
socket.id = self.generateId(nsp);
|
||||
});
|
||||
|
||||
if (this.autoConnect) {
|
||||
// manually call here since connecting event is fired before listening
|
||||
onConnecting();
|
||||
}
|
||||
}
|
||||
|
||||
function onConnecting () {
|
||||
if (!~indexOf(self.connecting, socket)) {
|
||||
self.connecting.push(socket);
|
||||
}
|
||||
}
|
||||
|
||||
return socket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon a socket close.
|
||||
*
|
||||
* @param {Socket} socket
|
||||
*/
|
||||
|
||||
Manager.prototype.destroy = function (socket) {
|
||||
var index = indexOf(this.connecting, socket);
|
||||
if (~index) this.connecting.splice(index, 1);
|
||||
if (this.connecting.length) return;
|
||||
|
||||
this.close();
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes a packet.
|
||||
*
|
||||
* @param {Object} packet
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.packet = function (packet) {
|
||||
debug('writing packet %j', packet);
|
||||
var self = this;
|
||||
if (packet.query && packet.type === 0) packet.nsp += '?' + packet.query;
|
||||
|
||||
if (!self.encoding) {
|
||||
// encode, then write to engine with result
|
||||
self.encoding = true;
|
||||
this.encoder.encode(packet, function (encodedPackets) {
|
||||
for (var i = 0; i < encodedPackets.length; i++) {
|
||||
self.engine.write(encodedPackets[i], packet.options);
|
||||
}
|
||||
self.encoding = false;
|
||||
self.processPacketQueue();
|
||||
});
|
||||
} else { // add packet to the queue
|
||||
self.packetBuffer.push(packet);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If packet buffer is non-empty, begins encoding the
|
||||
* next packet in line.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.processPacketQueue = function () {
|
||||
if (this.packetBuffer.length > 0 && !this.encoding) {
|
||||
var pack = this.packetBuffer.shift();
|
||||
this.packet(pack);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clean up transport subscriptions and packet buffer.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.cleanup = function () {
|
||||
debug('cleanup');
|
||||
|
||||
var subsLength = this.subs.length;
|
||||
for (var i = 0; i < subsLength; i++) {
|
||||
var sub = this.subs.shift();
|
||||
sub.destroy();
|
||||
}
|
||||
|
||||
this.packetBuffer = [];
|
||||
this.encoding = false;
|
||||
this.lastPing = null;
|
||||
|
||||
this.decoder.destroy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the current socket.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.close =
|
||||
Manager.prototype.disconnect = function () {
|
||||
debug('disconnect');
|
||||
this.skipReconnect = true;
|
||||
this.reconnecting = false;
|
||||
if ('opening' === this.readyState) {
|
||||
// `onclose` will not fire because
|
||||
// an open event never happened
|
||||
this.cleanup();
|
||||
}
|
||||
this.backoff.reset();
|
||||
this.readyState = 'closed';
|
||||
if (this.engine) this.engine.close();
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon engine close.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.onclose = function (reason) {
|
||||
debug('onclose');
|
||||
|
||||
this.cleanup();
|
||||
this.backoff.reset();
|
||||
this.readyState = 'closed';
|
||||
this.emit('close', reason);
|
||||
|
||||
if (this._reconnection && !this.skipReconnect) {
|
||||
this.reconnect();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt a reconnection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.reconnect = function () {
|
||||
if (this.reconnecting || this.skipReconnect) return this;
|
||||
|
||||
var self = this;
|
||||
|
||||
if (this.backoff.attempts >= this._reconnectionAttempts) {
|
||||
debug('reconnect failed');
|
||||
this.backoff.reset();
|
||||
this.emitAll('reconnect_failed');
|
||||
this.reconnecting = false;
|
||||
} else {
|
||||
var delay = this.backoff.duration();
|
||||
debug('will wait %dms before reconnect attempt', delay);
|
||||
|
||||
this.reconnecting = true;
|
||||
var timer = setTimeout(function () {
|
||||
if (self.skipReconnect) return;
|
||||
|
||||
debug('attempting reconnect');
|
||||
self.emitAll('reconnect_attempt', self.backoff.attempts);
|
||||
self.emitAll('reconnecting', self.backoff.attempts);
|
||||
|
||||
// check again for the case socket closed in above events
|
||||
if (self.skipReconnect) return;
|
||||
|
||||
self.open(function (err) {
|
||||
if (err) {
|
||||
debug('reconnect attempt error');
|
||||
self.reconnecting = false;
|
||||
self.reconnect();
|
||||
self.emitAll('reconnect_error', err.data);
|
||||
} else {
|
||||
debug('reconnect success');
|
||||
self.onreconnect();
|
||||
}
|
||||
});
|
||||
}, delay);
|
||||
|
||||
this.subs.push({
|
||||
destroy: function () {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon successful reconnect.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Manager.prototype.onreconnect = function () {
|
||||
var attempt = this.backoff.attempts;
|
||||
this.reconnecting = false;
|
||||
this.backoff.reset();
|
||||
this.updateSocketIds();
|
||||
this.emitAll('reconnect', attempt);
|
||||
};
|
24
node_modules/socket.io-client/lib/on.js
generated
vendored
Normal file
24
node_modules/socket.io-client/lib/on.js
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = on;
|
||||
|
||||
/**
|
||||
* Helper for subscriptions.
|
||||
*
|
||||
* @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
|
||||
* @param {String} event name
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function on (obj, ev, fn) {
|
||||
obj.on(ev, fn);
|
||||
return {
|
||||
destroy: function () {
|
||||
obj.removeListener(ev, fn);
|
||||
}
|
||||
};
|
||||
}
|
438
node_modules/socket.io-client/lib/socket.js
generated
vendored
Normal file
438
node_modules/socket.io-client/lib/socket.js
generated
vendored
Normal file
@ -0,0 +1,438 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var parser = require('socket.io-parser');
|
||||
var Emitter = require('component-emitter');
|
||||
var toArray = require('to-array');
|
||||
var on = require('./on');
|
||||
var bind = require('component-bind');
|
||||
var debug = require('debug')('socket.io-client:socket');
|
||||
var parseqs = require('parseqs');
|
||||
var hasBin = require('has-binary2');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = Socket;
|
||||
|
||||
/**
|
||||
* Internal events (blacklisted).
|
||||
* These events can't be emitted by the user.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var events = {
|
||||
connect: 1,
|
||||
connect_error: 1,
|
||||
connect_timeout: 1,
|
||||
connecting: 1,
|
||||
disconnect: 1,
|
||||
error: 1,
|
||||
reconnect: 1,
|
||||
reconnect_attempt: 1,
|
||||
reconnect_failed: 1,
|
||||
reconnect_error: 1,
|
||||
reconnecting: 1,
|
||||
ping: 1,
|
||||
pong: 1
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut to `Emitter#emit`.
|
||||
*/
|
||||
|
||||
var emit = Emitter.prototype.emit;
|
||||
|
||||
/**
|
||||
* `Socket` constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Socket (io, nsp, opts) {
|
||||
this.io = io;
|
||||
this.nsp = nsp;
|
||||
this.json = this; // compat
|
||||
this.ids = 0;
|
||||
this.acks = {};
|
||||
this.receiveBuffer = [];
|
||||
this.sendBuffer = [];
|
||||
this.connected = false;
|
||||
this.disconnected = true;
|
||||
this.flags = {};
|
||||
if (opts && opts.query) {
|
||||
this.query = opts.query;
|
||||
}
|
||||
if (this.io.autoConnect) this.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix in `Emitter`.
|
||||
*/
|
||||
|
||||
Emitter(Socket.prototype);
|
||||
|
||||
/**
|
||||
* Subscribe to open, close and packet events
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.subEvents = function () {
|
||||
if (this.subs) return;
|
||||
|
||||
var io = this.io;
|
||||
this.subs = [
|
||||
on(io, 'open', bind(this, 'onopen')),
|
||||
on(io, 'packet', bind(this, 'onpacket')),
|
||||
on(io, 'close', bind(this, 'onclose'))
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* "Opens" the socket.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.open =
|
||||
Socket.prototype.connect = function () {
|
||||
if (this.connected) return this;
|
||||
|
||||
this.subEvents();
|
||||
this.io.open(); // ensure open
|
||||
if ('open' === this.io.readyState) this.onopen();
|
||||
this.emit('connecting');
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a `message` event.
|
||||
*
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.send = function () {
|
||||
var args = toArray(arguments);
|
||||
args.unshift('message');
|
||||
this.emit.apply(this, args);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Override `emit`.
|
||||
* If the event is in `events`, it's emitted normally.
|
||||
*
|
||||
* @param {String} event name
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.emit = function (ev) {
|
||||
if (events.hasOwnProperty(ev)) {
|
||||
emit.apply(this, arguments);
|
||||
return this;
|
||||
}
|
||||
|
||||
var args = toArray(arguments);
|
||||
var packet = {
|
||||
type: (this.flags.binary !== undefined ? this.flags.binary : hasBin(args)) ? parser.BINARY_EVENT : parser.EVENT,
|
||||
data: args
|
||||
};
|
||||
|
||||
packet.options = {};
|
||||
packet.options.compress = !this.flags || false !== this.flags.compress;
|
||||
|
||||
// event ack callback
|
||||
if ('function' === typeof args[args.length - 1]) {
|
||||
debug('emitting packet with ack id %d', this.ids);
|
||||
this.acks[this.ids] = args.pop();
|
||||
packet.id = this.ids++;
|
||||
}
|
||||
|
||||
if (this.connected) {
|
||||
this.packet(packet);
|
||||
} else {
|
||||
this.sendBuffer.push(packet);
|
||||
}
|
||||
|
||||
this.flags = {};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a packet.
|
||||
*
|
||||
* @param {Object} packet
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.packet = function (packet) {
|
||||
packet.nsp = this.nsp;
|
||||
this.io.packet(packet);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon engine `open`.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onopen = function () {
|
||||
debug('transport is open - connecting');
|
||||
|
||||
// write connect packet if necessary
|
||||
if ('/' !== this.nsp) {
|
||||
if (this.query) {
|
||||
var query = typeof this.query === 'object' ? parseqs.encode(this.query) : this.query;
|
||||
debug('sending connect packet with query %s', query);
|
||||
this.packet({type: parser.CONNECT, query: query});
|
||||
} else {
|
||||
this.packet({type: parser.CONNECT});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon engine `close`.
|
||||
*
|
||||
* @param {String} reason
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onclose = function (reason) {
|
||||
debug('close (%s)', reason);
|
||||
this.connected = false;
|
||||
this.disconnected = true;
|
||||
delete this.id;
|
||||
this.emit('disconnect', reason);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called with socket packet.
|
||||
*
|
||||
* @param {Object} packet
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onpacket = function (packet) {
|
||||
var sameNamespace = packet.nsp === this.nsp;
|
||||
var rootNamespaceError = packet.type === parser.ERROR && packet.nsp === '/';
|
||||
|
||||
if (!sameNamespace && !rootNamespaceError) return;
|
||||
|
||||
switch (packet.type) {
|
||||
case parser.CONNECT:
|
||||
this.onconnect();
|
||||
break;
|
||||
|
||||
case parser.EVENT:
|
||||
this.onevent(packet);
|
||||
break;
|
||||
|
||||
case parser.BINARY_EVENT:
|
||||
this.onevent(packet);
|
||||
break;
|
||||
|
||||
case parser.ACK:
|
||||
this.onack(packet);
|
||||
break;
|
||||
|
||||
case parser.BINARY_ACK:
|
||||
this.onack(packet);
|
||||
break;
|
||||
|
||||
case parser.DISCONNECT:
|
||||
this.ondisconnect();
|
||||
break;
|
||||
|
||||
case parser.ERROR:
|
||||
this.emit('error', packet.data);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon a server event.
|
||||
*
|
||||
* @param {Object} packet
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onevent = function (packet) {
|
||||
var args = packet.data || [];
|
||||
debug('emitting event %j', args);
|
||||
|
||||
if (null != packet.id) {
|
||||
debug('attaching ack callback to event');
|
||||
args.push(this.ack(packet.id));
|
||||
}
|
||||
|
||||
if (this.connected) {
|
||||
emit.apply(this, args);
|
||||
} else {
|
||||
this.receiveBuffer.push(args);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Produces an ack callback to emit with an event.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.ack = function (id) {
|
||||
var self = this;
|
||||
var sent = false;
|
||||
return function () {
|
||||
// prevent double callbacks
|
||||
if (sent) return;
|
||||
sent = true;
|
||||
var args = toArray(arguments);
|
||||
debug('sending ack %j', args);
|
||||
|
||||
self.packet({
|
||||
type: hasBin(args) ? parser.BINARY_ACK : parser.ACK,
|
||||
id: id,
|
||||
data: args
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon a server acknowlegement.
|
||||
*
|
||||
* @param {Object} packet
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onack = function (packet) {
|
||||
var ack = this.acks[packet.id];
|
||||
if ('function' === typeof ack) {
|
||||
debug('calling ack %s with %j', packet.id, packet.data);
|
||||
ack.apply(this, packet.data);
|
||||
delete this.acks[packet.id];
|
||||
} else {
|
||||
debug('bad ack %s', packet.id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon server connect.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.onconnect = function () {
|
||||
this.connected = true;
|
||||
this.disconnected = false;
|
||||
this.emit('connect');
|
||||
this.emitBuffered();
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit buffered events (received and emitted).
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.emitBuffered = function () {
|
||||
var i;
|
||||
for (i = 0; i < this.receiveBuffer.length; i++) {
|
||||
emit.apply(this, this.receiveBuffer[i]);
|
||||
}
|
||||
this.receiveBuffer = [];
|
||||
|
||||
for (i = 0; i < this.sendBuffer.length; i++) {
|
||||
this.packet(this.sendBuffer[i]);
|
||||
}
|
||||
this.sendBuffer = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon server disconnect.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Socket.prototype.ondisconnect = function () {
|
||||
debug('server disconnect (%s)', this.nsp);
|
||||
this.destroy();
|
||||
this.onclose('io server disconnect');
|
||||
};
|
||||
|
||||
/**
|
||||
* Called upon forced client/server side disconnections,
|
||||
* this method ensures the manager stops tracking us and
|
||||
* that reconnections don't get triggered for this.
|
||||
*
|
||||
* @api private.
|
||||
*/
|
||||
|
||||
Socket.prototype.destroy = function () {
|
||||
if (this.subs) {
|
||||
// clean subscriptions to avoid reconnections
|
||||
for (var i = 0; i < this.subs.length; i++) {
|
||||
this.subs[i].destroy();
|
||||
}
|
||||
this.subs = null;
|
||||
}
|
||||
|
||||
this.io.destroy(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disconnects the socket manually.
|
||||
*
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.close =
|
||||
Socket.prototype.disconnect = function () {
|
||||
if (this.connected) {
|
||||
debug('performing disconnect (%s)', this.nsp);
|
||||
this.packet({ type: parser.DISCONNECT });
|
||||
}
|
||||
|
||||
// remove socket from pool
|
||||
this.destroy();
|
||||
|
||||
if (this.connected) {
|
||||
// fire events
|
||||
this.onclose('io client disconnect');
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the compress flag.
|
||||
*
|
||||
* @param {Boolean} if `true`, compresses the sending data
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.compress = function (compress) {
|
||||
this.flags.compress = compress;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the binary flag
|
||||
*
|
||||
* @param {Boolean} whether the emitted data contains binary
|
||||
* @return {Socket} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Socket.prototype.binary = function (binary) {
|
||||
this.flags.binary = binary;
|
||||
return this;
|
||||
};
|
75
node_modules/socket.io-client/lib/url.js
generated
vendored
Normal file
75
node_modules/socket.io-client/lib/url.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var parseuri = require('parseuri');
|
||||
var debug = require('debug')('socket.io-client:url');
|
||||
|
||||
/**
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = url;
|
||||
|
||||
/**
|
||||
* URL parser.
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Object} An object meant to mimic window.location.
|
||||
* Defaults to window.location.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function url (uri, loc) {
|
||||
var obj = uri;
|
||||
|
||||
// default to window.location
|
||||
loc = loc || (typeof location !== 'undefined' && location);
|
||||
if (null == uri) uri = loc.protocol + '//' + loc.host;
|
||||
|
||||
// relative path support
|
||||
if ('string' === typeof uri) {
|
||||
if ('/' === uri.charAt(0)) {
|
||||
if ('/' === uri.charAt(1)) {
|
||||
uri = loc.protocol + uri;
|
||||
} else {
|
||||
uri = loc.host + uri;
|
||||
}
|
||||
}
|
||||
|
||||
if (!/^(https?|wss?):\/\//.test(uri)) {
|
||||
debug('protocol-less url %s', uri);
|
||||
if ('undefined' !== typeof loc) {
|
||||
uri = loc.protocol + '//' + uri;
|
||||
} else {
|
||||
uri = 'https://' + uri;
|
||||
}
|
||||
}
|
||||
|
||||
// parse
|
||||
debug('parse %s', uri);
|
||||
obj = parseuri(uri);
|
||||
}
|
||||
|
||||
// make sure we treat `localhost:80` and `localhost` equally
|
||||
if (!obj.port) {
|
||||
if (/^(http|ws)$/.test(obj.protocol)) {
|
||||
obj.port = '80';
|
||||
} else if (/^(http|ws)s$/.test(obj.protocol)) {
|
||||
obj.port = '443';
|
||||
}
|
||||
}
|
||||
|
||||
obj.path = obj.path || '/';
|
||||
|
||||
var ipv6 = obj.host.indexOf(':') !== -1;
|
||||
var host = ipv6 ? '[' + obj.host + ']' : obj.host;
|
||||
|
||||
// define unique id
|
||||
obj.id = obj.protocol + '://' + host + ':' + obj.port;
|
||||
// define href
|
||||
obj.href = obj.protocol + '://' + host + (loc && loc.port === obj.port ? '' : (':' + obj.port));
|
||||
|
||||
return obj;
|
||||
}
|
Reference in New Issue
Block a user