mirror of
https://github.com/viq/NewsBlur.git
synced 2025-08-05 16:49:45 +00:00
245 lines
5.1 KiB
JavaScript
245 lines
5.1 KiB
JavaScript
/**
|
|
* socket.io
|
|
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
|
|
* 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);
|
|
|
|
/**
|
|
* 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.open = 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.close && this.open) 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.open = 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.open = false;
|
|
this.socket.onClose();
|
|
this.onDisconnect();
|
|
};
|
|
|
|
/**
|
|
* Generates a connection url based on the Socket.IO URL Protocol.
|
|
* See <https://github.com/learnboost/socket.io-node/> 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
|
|
);
|