@emartech/faye-redis-sharded
Version:
Redis backend engine for Faye with support for sharding
138 lines (103 loc) • 3.94 kB
JavaScript
Faye.Transport = Faye.extend(Faye.Class({
MAX_DELAY: 0,
batching: true,
initialize: function(client, endpoint) {
this._client = client;
this.endpoint = endpoint;
this._outbox = [];
},
close: function() {},
encode: function(envelopes) {
return '';
},
send: function(envelope) {
var message = envelope.message;
this.debug('Client ? sending message to ?: ?',
this._client._clientId, Faye.URI.stringify(this.endpoint), message);
if (!this.batching) return this.request([envelope]);
this._outbox.push(envelope);
if (message.channel === Faye.Channel.HANDSHAKE)
return this.addTimeout('publish', 0.01, this.flush, this);
if (message.channel === Faye.Channel.CONNECT)
this._connectMessage = message;
this.flushLargeBatch();
this.addTimeout('publish', this.MAX_DELAY, this.flush, this);
},
flush: function() {
this.removeTimeout('publish');
if (this._outbox.length > 1 && this._connectMessage)
this._connectMessage.advice = {timeout: 0};
var request = this.request(this._outbox), n = this._outbox.length;
while (n--)
this._outbox[n].errback(function() { if (request) request.abort() });
this._connectMessage = null;
this._outbox = [];
},
flushLargeBatch: function() {
var string = this.encode(this._outbox);
if (string.length < this._client.maxRequestSize) return;
var last = this._outbox.pop();
this.flush();
if (last) this._outbox.push(last);
},
receive: function(envelopes, responses) {
var n = envelopes.length;
while (n--) envelopes[n].setDeferredStatus('succeeded');
responses = [].concat(responses);
this.debug('Client ? received from ?: ?',
this._client._clientId, Faye.URI.stringify(this.endpoint), responses);
for (var i = 0, m = responses.length; i < m; i++)
this._client.receiveMessage(responses[i]);
},
handleError: function(envelopes, immediate) {
var n = envelopes.length;
while (n--) envelopes[n].setDeferredStatus('failed', immediate);
},
_getCookies: function() {
var cookies = this._client.cookies,
url = Faye.URI.stringify(this.endpoint);
if (!cookies) return '';
return Faye.map(cookies.getCookiesSync(url), function(cookie) {
return cookie.cookieString();
}).join('; ');
},
_storeCookies: function(setCookie) {
var cookies = this._client.cookies,
url = Faye.URI.stringify(this.endpoint),
cookie;
if (!setCookie || !cookies) return;
setCookie = [].concat(setCookie);
for (var i = 0, n = setCookie.length; i < n; i++) {
cookie = Faye.Cookies.Cookie.parse(setCookie[i]);
cookies.setCookieSync(cookie, url);
}
}
}), {
get: function(client, allowed, disabled, callback, context) {
var endpoint = client.endpoint;
Faye.asyncEach(this._transports, function(pair, resume) {
var connType = pair[0], klass = pair[1],
connEndpoint = client.endpoints[connType] || endpoint;
if (Faye.indexOf(disabled, connType) >= 0)
return resume();
if (Faye.indexOf(allowed, connType) < 0) {
klass.isUsable(client, connEndpoint, function() {});
return resume();
}
klass.isUsable(client, connEndpoint, function(isUsable) {
if (!isUsable) return resume();
var transport = klass.hasOwnProperty('create') ? klass.create(client, connEndpoint) : new klass(client, connEndpoint);
callback.call(context, transport);
});
}, function() {
throw new Error('Could not find a usable connection type for ' + Faye.URI.stringify(endpoint));
});
},
register: function(type, klass) {
this._transports.push([type, klass]);
klass.prototype.connectionType = type;
},
_transports: []
});
Faye.extend(Faye.Transport.prototype, Faye.Logging);
Faye.extend(Faye.Transport.prototype, Faye.Timeouts);