aboutsummaryrefslogtreecommitdiffhomepage
path: root/node_modules/socket.io-client/lib/socket.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/socket.io-client/lib/socket.js')
-rw-r--r--node_modules/socket.io-client/lib/socket.js418
1 files changed, 418 insertions, 0 deletions
diff --git a/node_modules/socket.io-client/lib/socket.js b/node_modules/socket.io-client/lib/socket.js
new file mode 100644
index 0000000..702c602
--- /dev/null
+++ b/node_modules/socket.io-client/lib/socket.js
@@ -0,0 +1,418 @@
+
+/**
+ * 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');
+
+/**
+ * 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;
+ 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: 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);
+ }
+
+ delete 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) {
+ if (packet.nsp !== this.nsp) 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: 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 = this.flags || {};
+ this.flags.compress = compress;
+ return this;
+};