An HTTP Stream Listener Model in Javascript. This object can listen to an http stream that doesn't close, and forward chunks of incoming data to any subscribed listeners.
/**
* @fileOverview HttpStreamModel Module
* @version 1.0
*/
define(['jquery'], function($) {
require(['bind']);
'use strict';
var url;
var HttpStreamModel = {
XHR_READY_STATE_REQUEST_RECEIVED: 2,
listeners: [],
setUrl: function(url) {
url = url;
},
openStream: function() {
if (typeof window.XDomainRequest === 'undefined') {
this._openStreamXHR();
} else {
this._openStreamXDR();
}
},
/**
* Legacy IE
*/
_openStreamXDR: function() {
try {
var xdr = new XDomainRequest();
xdr.open("GET", url);
xdr.send();
xdr.onload = function() {
// ... would only get here if the connection closes
};
xdr.onerror = function() {
// error handline
};
xdr.onprogress = function() {
this.setResponse(xdr.responseText);
this.parseResponse();
this.notifyListeners();
}.bind(this);
} catch (e) {
this.log("[XDR] Exception: " + e);
}
},
/**
* Modern Browsers
*/
_openStreamXHR: function() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
// since our connection doesn't close, there's nothing to handle here
};
xhr.onerror = function() {
// error handling
};
xhr.onreadystatechange = function() {
try {
if (xhr.readyState > this.XHR_READY_STATE_REQUEST_RECEIVED) {
this.setResponse(xhr.responseText);
this.parseResponse();
this.notifyListeners();
}
}
catch (e){
// exception handling
}
}.bind(this);
xhr.open("GET", url, true);
xhr.send("Making request...");
},
setResponse: function(response) {
this.response = response;
},
/**
* The feed is not valid json, so we need to treat it as text, parse out the last object, and decode it to
* an object
*/
parseResponse: function() {
var lastObjectIndex = this.response.lastIndexOf("{");
var substring = $.trim(this.response.substring(lastObjectIndex)).replace(/(\r\n|\n|\r)/gm, "");
if (substring.length) {
try {
var latest = $.parseJSON(substring);
if (typeof latest !== 'undefined') {
this.latest = latest;
}
} catch (e) {
// silent
}
}
},
notifyListeners: function() {
if (typeof this.latest !== 'undefined') {
for (var listener in this.listeners) {
if (typeof this.listeners[listener] === 'function') {
this.listeners[listener](this.latest);
}
}
}
},
addListener: function(listener) {
if (typeof listener === 'function') {
this.listeners.push(listener);
}
},
log: function(msg) {
if (window.XDomainRequest) {
alert(msg);
} else {
console.log(msg);
}
}
};
return HttpStreamModel;
});