faye
Version:
Simple pub/sub messaging for the web
98 lines (76 loc) • 2.69 kB
JavaScript
;
var Class = require('../util/class'),
URI = require('../util/uri'),
copyObject = require('../util/copy_object'),
assign = require('../util/assign'),
Deferrable = require('../mixins/deferrable'),
Transport = require('./transport'),
XHR = require('./xhr');
var EventSource = assign(Class(Transport, {
initialize: function(dispatcher, endpoint) {
Transport.prototype.initialize.call(this, dispatcher, endpoint);
if (!global.EventSource) return this.setDeferredStatus('failed');
this._xhr = new XHR(dispatcher, endpoint);
endpoint = copyObject(endpoint);
endpoint.pathname += '/' + dispatcher.clientId;
var socket = new global.EventSource(URI.stringify(endpoint)),
self = this;
socket.onopen = function() {
self._everConnected = true;
self.setDeferredStatus('succeeded');
};
socket.onerror = function() {
if (self._everConnected) {
self._handleError([]);
} else {
self.setDeferredStatus('failed');
socket.close();
}
};
socket.onmessage = function(event) {
var replies;
try { replies = JSON.parse(event.data) } catch (error) {}
if (replies)
self._receive(replies);
else
self._handleError([]);
};
this._socket = socket;
},
close: function() {
if (!this._socket) return;
this._socket.onopen = this._socket.onerror = this._socket.onmessage = null;
this._socket.close();
delete this._socket;
},
isUsable: function(callback, context) {
this.callback(function() { callback.call(context, true) });
this.errback(function() { callback.call(context, false) });
},
encode: function(messages) {
return this._xhr.encode(messages);
},
request: function(messages) {
return this._xhr.request(messages);
}
}), {
isUsable: function(dispatcher, endpoint, callback, context) {
var id = dispatcher.clientId;
if (!id) return callback.call(context, false);
XHR.isUsable(dispatcher, endpoint, function(usable) {
if (!usable) return callback.call(context, false);
this.create(dispatcher, endpoint).isUsable(callback, context);
}, this);
},
create: function(dispatcher, endpoint) {
var sockets = dispatcher.transports.eventsource = dispatcher.transports.eventsource || {},
id = dispatcher.clientId;
var url = copyObject(endpoint);
url.pathname += '/' + (id || '');
url = URI.stringify(url);
sockets[url] = sockets[url] || new this(dispatcher, endpoint);
return sockets[url];
}
});
assign(EventSource.prototype, Deferrable);
module.exports = EventSource;