/** * socket.io * Copyright(c) 2011 LearnBoost * MIT Licensed */ (function (exports, io) { /** * Expose constructor. */ exports.Transport = Transport; /** * This is the transport template for all supported transport methods. * * @constructor * @api public */ function Transport (socket, sessid) { this.socket = socket; this.sessid = sessid; }; /** * Apply EventEmitter mixin. */ io.util.mixin(Transport, io.EventEmitter); /** * Indicates whether heartbeats is enabled for this transport * * @api private */ Transport.prototype.heartbeats = function () { return true; }; /** * Handles the response from the server. When a new response is received * it will automatically update the timeout, decode the message and * forwards the response to the onMessage function for further processing. * * @param {String} data Response from the server. * @api private */ Transport.prototype.onData = function (data) { this.clearCloseTimeout(); // If the connection in currently open (or in a reopening state) reset the close // timeout since we have just received data. This check is necessary so // that we don't reset the timeout on an explicitly disconnected connection. if (this.socket.connected || this.socket.connecting || this.socket.reconnecting) { this.setCloseTimeout(); } if (data !== '') { // todo: we should only do decodePayload for xhr transports var msgs = io.parser.decodePayload(data); if (msgs && msgs.length) { for (var i = 0, l = msgs.length; i < l; i++) { this.onPacket(msgs[i]); } } } return this; }; /** * Handles packets. * * @api private */ Transport.prototype.onPacket = function (packet) { this.socket.setHeartbeatTimeout(); if (packet.type == 'heartbeat') { return this.onHeartbeat(); } if (packet.type == 'connect' && packet.endpoint == '') { this.onConnect(); } if (packet.type == 'error' && packet.advice == 'reconnect') { this.isOpen = false; } this.socket.onPacket(packet); return this; }; /** * Sets close timeout * * @api private */ Transport.prototype.setCloseTimeout = function () { if (!this.closeTimeout) { var self = this; this.closeTimeout = setTimeout(function () { self.onDisconnect(); }, this.socket.closeTimeout); } }; /** * Called when transport disconnects. * * @api private */ Transport.prototype.onDisconnect = function () { if (this.isOpen) this.close(); this.clearTimeouts(); this.socket.onDisconnect(); return this; }; /** * Called when transport connects * * @api private */ Transport.prototype.onConnect = function () { this.socket.onConnect(); return this; }; /** * Clears close timeout * * @api private */ Transport.prototype.clearCloseTimeout = function () { if (this.closeTimeout) { clearTimeout(this.closeTimeout); this.closeTimeout = null; } }; /** * Clear timeouts * * @api private */ Transport.prototype.clearTimeouts = function () { this.clearCloseTimeout(); if (this.reopenTimeout) { clearTimeout(this.reopenTimeout); } }; /** * Sends a packet * * @param {Object} packet object. * @api private */ Transport.prototype.packet = function (packet) { this.send(io.parser.encodePacket(packet)); }; /** * Send the received heartbeat message back to server. So the server * knows we are still connected. * * @param {String} heartbeat Heartbeat response from the server. * @api private */ Transport.prototype.onHeartbeat = function (heartbeat) { this.packet({ type: 'heartbeat' }); }; /** * Called when the transport opens. * * @api private */ Transport.prototype.onOpen = function () { this.isOpen = true; this.clearCloseTimeout(); this.socket.onOpen(); }; /** * Notifies the base when the connection with the Socket.IO server * has been disconnected. * * @api private */ Transport.prototype.onClose = function () { var self = this; /* FIXME: reopen delay causing a infinit loop this.reopenTimeout = setTimeout(function () { self.open(); }, this.socket.options['reopen delay']);*/ this.isOpen = false; this.socket.onClose(); this.onDisconnect(); }; /** * Generates a connection url based on the Socket.IO URL Protocol. * See for more details. * * @returns {String} Connection url * @api private */ Transport.prototype.prepareUrl = function () { var options = this.socket.options; return this.scheme() + '://' + options.host + ':' + options.port + '/' + options.resource + '/' + io.protocol + '/' + this.name + '/' + this.sessid; }; /** * Checks if the transport is ready to start a connection. * * @param {Socket} socket The socket instance that needs a transport * @param {Function} fn The callback * @api private */ Transport.prototype.ready = function (socket, fn) { fn.call(this); }; })( 'undefined' != typeof io ? io : module.exports , 'undefined' != typeof io ? io : module.parent.exports );