2012-01-02 18:24:53 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* socket.io
|
|
|
|
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
|
|
|
|
* MIT Licensed
|
|
|
|
*/
|
|
|
|
|
|
|
|
(function (exports, io, global) {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Expose constructor.
|
|
|
|
*/
|
|
|
|
|
|
|
|
exports['xhr-polling'] = XHRPolling;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The XHR-polling transport uses long polling XHR requests to create a
|
|
|
|
* "persistent" connection with the server.
|
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @api public
|
|
|
|
*/
|
|
|
|
|
|
|
|
function XHRPolling () {
|
|
|
|
io.Transport.XHR.apply(this, arguments);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Inherits from XHR transport.
|
|
|
|
*/
|
|
|
|
|
|
|
|
io.util.inherit(XHRPolling, io.Transport.XHR);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Merge the properties from XHR transport
|
|
|
|
*/
|
|
|
|
|
|
|
|
io.util.merge(XHRPolling, io.Transport.XHR);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Transport name
|
|
|
|
*
|
|
|
|
* @api public
|
|
|
|
*/
|
|
|
|
|
|
|
|
XHRPolling.prototype.name = 'xhr-polling';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Establish a connection, for iPhone and Android this will be done once the page
|
|
|
|
* is loaded.
|
|
|
|
*
|
|
|
|
* @returns {Transport} Chaining.
|
|
|
|
* @api public
|
|
|
|
*/
|
|
|
|
|
|
|
|
XHRPolling.prototype.open = function () {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
io.Transport.XHR.prototype.open.call(self);
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Starts a XHR request to wait for incoming messages.
|
|
|
|
*
|
|
|
|
* @api private
|
|
|
|
*/
|
|
|
|
|
|
|
|
function empty () {};
|
|
|
|
|
|
|
|
XHRPolling.prototype.get = function () {
|
|
|
|
if (!this.open) return;
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
function stateChange () {
|
|
|
|
if (this.readyState == 4) {
|
|
|
|
this.onreadystatechange = empty;
|
|
|
|
|
|
|
|
if (this.status == 200) {
|
|
|
|
self.onData(this.responseText);
|
|
|
|
self.get();
|
|
|
|
} else {
|
|
|
|
self.onClose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
function onload () {
|
|
|
|
this.onload = empty;
|
2012-04-03 12:22:27 -07:00
|
|
|
this.onerror = empty;
|
2012-01-02 18:24:53 -08:00
|
|
|
self.onData(this.responseText);
|
|
|
|
self.get();
|
|
|
|
};
|
|
|
|
|
2012-04-03 12:22:27 -07:00
|
|
|
function onerror () {
|
|
|
|
self.onClose();
|
|
|
|
};
|
|
|
|
|
2012-01-02 18:24:53 -08:00
|
|
|
this.xhr = this.request();
|
|
|
|
|
|
|
|
if (global.XDomainRequest && this.xhr instanceof XDomainRequest) {
|
2012-04-03 12:22:27 -07:00
|
|
|
this.xhr.onload = onload;
|
|
|
|
this.xhr.onerror = onerror;
|
2012-01-02 18:24:53 -08:00
|
|
|
} else {
|
|
|
|
this.xhr.onreadystatechange = stateChange;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.xhr.send(null);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle the unclean close behavior.
|
|
|
|
*
|
|
|
|
* @api private
|
|
|
|
*/
|
|
|
|
|
|
|
|
XHRPolling.prototype.onClose = function () {
|
|
|
|
io.Transport.XHR.prototype.onClose.call(this);
|
|
|
|
|
|
|
|
if (this.xhr) {
|
2012-04-03 12:22:27 -07:00
|
|
|
this.xhr.onreadystatechange = this.xhr.onload = this.xhr.onerror = empty;
|
2012-01-02 18:24:53 -08:00
|
|
|
try {
|
|
|
|
this.xhr.abort();
|
|
|
|
} catch(e){}
|
|
|
|
this.xhr = null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Webkit based browsers show a infinit spinner when you start a XHR request
|
|
|
|
* before the browsers onload event is called so we need to defer opening of
|
|
|
|
* the transport until the onload event is called. Wrapping the cb in our
|
|
|
|
* defer method solve this.
|
|
|
|
*
|
|
|
|
* @param {Socket} socket The socket instance that needs a transport
|
|
|
|
* @param {Function} fn The callback
|
|
|
|
* @api private
|
|
|
|
*/
|
|
|
|
|
|
|
|
XHRPolling.prototype.ready = function (socket, fn) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
io.util.defer(function () {
|
|
|
|
fn.call(self);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add the transport to your public io.transports array.
|
|
|
|
*
|
|
|
|
* @api private
|
|
|
|
*/
|
|
|
|
|
|
|
|
io.transports.push('xhr-polling');
|
|
|
|
|
|
|
|
})(
|
|
|
|
'undefined' != typeof io ? io.Transport : module.exports
|
|
|
|
, 'undefined' != typeof io ? io : module.parent.exports
|
|
|
|
, this
|
|
|
|
);
|