I ported the Atmosphere client from jQuery to KONtx. Basically, I copy their jquery plugin code and strip all irrelevant parts (like http streaming, websocket support as Yahoo WDK does not support them.) Hope this will help others:
CODE
var Atmosphere = new KONtx.Class({
ClassName: 'Atmosphere',
config: {},
version : 0.7,
response : {
status: 200,
responseBody : '',
headers : [],
state : "messageReceived",
transport : "polling",
push : [],
error: null,
id : 0
},
request : {},
abortingConnection: false,
callbacks: [],
activeTransport : null,
subscribe: function(url, callback, request) {
this.request = $merge({
timeout: 300000,
method: 'GET',
headers: {},
contentType : '',
cache: true,
async: true,
ifModified: false,
callback: null,
dataType: '',
url : url,
data : '',
suspend : true,
maxRequest : 60,
lastIndex : 0,
requestCount : 0,
fallbackTransport : 'streaming',
transport : 'long-polling',
}, request);
if (callback != null) {
this.addCallback(callback);
this.request.callback = callback;
}
if (this.request.transport != this.activeTransport) {
this.closeSuspendedConnection();
}
this.activeTransport = this.request.transport;
this.executeRequest();
},
/**
* Always make sure one transport is used, not two at the same time except for Websocket.
*/
closeSuspendedConnection : function () {
this.abortingConnection = true;
if (this.activeRequest != null) {
this.activeRequest.abort();
}
this.abortingConnection = false;
},
executeRequest: function() {
var self = this;
if (this.request.requestCount++ < this.request.maxRequest) {
this.response.push = function (url) {
this.request.callback = null;
self.publish(url, null, this.request);
};
var request = this.request;
var response = this.response;
if (request.transport != 'polling') {
response.transport = request.transport;
}
var ajaxRequest = new XMLHttpRequest();
if (request.suspend) {
activeRequest = ajaxRequest;
}
ajaxRequest.open(request.method, request.url, true);
ajaxRequest.setRequestHeader("X-Atmosphere-Framework", this.version);
ajaxRequest.setRequestHeader("X-Atmosphere-Transport", request.transport);
ajaxRequest.setRequestHeader("X-Cache-Date", new Date().getTime());
if (this.request.contentType != '') {
ajaxRequest.setRequestHeader("Content-Type", this.request.contentType);
}
for (var x in request.headers) {
ajaxRequest.setRequestHeader(x, request.headers[x]);
}
ajaxRequest.onerror = function() {
error = true;
try {
response.status = XMLHttpRequest.status;
} catch(e) {
response.status = 404;
}
response.state = "error";
this.invokeCallback(response);
ajaxRequest.abort();
activeRequest = null;
}
ajaxRequest.onreadystatechange = function() {
if (this.abortingConnection) return;
var junkForWebkit = false;
var update = false;
if (ajaxRequest.readyState == 4) {
this.request = request;
if (request.suspend && ajaxRequest.status == 200) {
self.executeRequest();
}
} else if (ajaxRequest.readyState == 3 && ajaxRequest.status == 200) {
update = true;
} else {
KONtx.utility.timer.clearTimeout(request.id);
}
if (update || !$empty(ajaxRequest.responseText)) {
response.responseBody = ajaxRequest.responseText;
try {
response.status = ajaxRequest.status;
response.headers = ajaxRequest.getAllResponseHeaders();
} catch(e) {
response.status = 404;
}
if (request.suspend) {
response.state = "messageReceived";
} else {
response.state = "messagePublished";
}
if (response.responseBody.indexOf("parent.callback") != -1) {
var index = 0;
var responseBody = response.responseBody;
while ( responseBody.indexOf("('", index) != -1) {
var start = responseBody.indexOf("('", index) + 2;
var end = responseBody.indexOf("')", index);
response.responseBody = responseBody.substring(start, end);
index = end + 2;
self.invokeCallback(response);
}
} else {
self.invokeCallback(response);
}
}
};
ajaxRequest.send(request.data);
if (request.suspend) {
request.id = KONtx.utility.timer.setTimeout(function() {
ajaxRequest.abort();
self.subscribe(request.url, null, request);
}, request.timeout);
}
} else {
log("Max re-connection reached.");
}
},
addCallback: function(func) {
if (!Array.contains(func, this.callbacks)) {
this.callbacks.push(func);
}
},
removeCallback: function(func) {
var result = Array.find(func, this.callbacks);
if (result) {
this.callbacks.splice(result[0]);
}
},
invokeCallback: function(response) {
log("Invoking " + this.callbacks.length + " callbacks");
if (this.callbacks.length > 0) {
for each (var func in this.callbacks) {
func(response);
}
}
},
publish: function(url, callback, request) {
this.request = jQuery.extend({
connected: false,
timeout: 60000,
method: 'POST',
contentType : '',
headers: {},
cache: true,
async: true,
ifModified: false,
callback: null,
dataType: '',
url : url,
data : '',
suspend : false,
maxRequest : 60,
requestCount : 0,
transport: 'polling'
}, request);
if (callback != null) {
this.addCallback(callback);
}
this.request.transport = 'polling';
this.executeRequest();
},
close : function() {
this.closeSuspendedConnection();
}
});