Created
May 11, 2012 03:48
-
-
Save rpgmaker/2657403 to your computer and use it in GitHub Desktop.
First Draft for JS API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
String.format = function (text) { | |
if (arguments.length <= 1) return text; | |
var length = arguments.length - 2, token; | |
for (token = 0; token <= length; token++) { | |
text = text.replace(new RegExp("\\{" + token + "\\}", "gi"), arguments[token + 1]); | |
} | |
return text; | |
}; | |
jQuery.support.cors = true; | |
(function (jQuery) { | |
if (window.XDomainRequest) { | |
jQuery.ajaxTransport(function (s) { | |
if (s.crossDomain && s.async) { | |
if (s.timeout) { | |
s.xdrTimeout = s.timeout; | |
delete s.timeout; | |
} | |
var xdr; | |
return { | |
send: function (_, complete) { | |
function callback(status, statusText, responses, responseHeaders) { | |
xdr.onload = xdr.onerror = xdr.ontimeout = jQuery.noop; | |
xdr = undefined; | |
complete(status, statusText, responses, responseHeaders); | |
} | |
xdr = new XDomainRequest(); | |
xdr.open(s.type, s.url); | |
xdr.onload = function () { | |
callback(200, "OK", { text: xdr.responseText }, "Content-Type: " + xdr.contentType); | |
}; | |
xdr.onerror = function () { | |
callback(404, "Not Found"); | |
}; | |
if (s.xdrTimeout) { | |
xdr.ontimeout = function () { | |
callback(0, "timeout"); | |
}; | |
xdr.timeout = s.xdrTimeout; | |
} | |
xdr.send((s.hasContent && s.data) || null); | |
}, | |
abort: function () { | |
if (xdr) { | |
xdr.onerror = jQuery.noop(); | |
xdr.abort(); | |
} | |
} | |
}; | |
} | |
}); | |
} | |
})(jQuery); | |
var PSERVICEBUS; | |
if (!PSERVICEBUS) PSERVICEBUS = {}; | |
(function (fn) { | |
var hubcounter = 0, | |
hubconnections = {}; | |
fn.hub = function () { | |
var self = this, | |
interval = 500, | |
transport = null, | |
active = false, | |
msgID = 0, | |
hubID = ++hubcounter, | |
name = "hub" + hubID, | |
url = null, | |
protocols = { | |
httpstreaming: 1, | |
serversent: 4, | |
ieforeverframe: 2, | |
foreverframe: 3 | |
}, | |
protocol = | |
($.browser.msie ? protocols.ieforeverframe : | |
$.browser.opera ? protocols.serversent : | |
$.browser.safari || $.browser.webkit || $.browser.mozilla ? | |
protocols.httpstreaming : protocols.foreverframe), | |
scope = function (f, context) { | |
return function () { return f.apply(context); }; | |
}, | |
xhrcallback = function () { | |
if (transport.readyState == 4) { self.close(); return; } | |
var messages = transport.responseText.match(/<comet>(.+?)<\/comet>/g); | |
while (messages && messages[msgID]) { | |
var message = messages[msgID].substring(7, messages[msgID].length - 8), | |
msg = JSON.parse(message); | |
self.onmessage(msg); | |
msgID++; | |
} | |
}, | |
checkframe = function () { | |
var iframe = transport.getElementById(name); | |
if (!iframe) return; | |
if (iframe.readyState === 'complete') { self.close(); return; } | |
setTimeout(scope(checkframe, self), interval); | |
}; | |
var _open = function (uri) { | |
if (active) return; | |
url = uri; | |
active = true; | |
switch (protocol) { | |
case protocols.httpstreaming: | |
transport = ("XDomainRequest" in window) ? new XDomainRequest() : | |
new XMLHttpRequest(); | |
transport.open("GET", url, true); | |
transport.onreadystatechange = scope(xhrcallback, self); | |
transport.send(null); | |
break; | |
case protocols.ieforeverframe: | |
transport = new ActiveXObject("htmlfile"); | |
transport.open(); | |
transport.write(String.format("<html><script>document.domain='{0}//{1}';</script></html>", document.location.protocol, document.domain)); | |
transport.close(); | |
transport.parentWindow.push = self.onmessage; | |
var div = transport.createElement("div"); | |
transport.body.appendChild(div); | |
div.innerHTML = String.format("<iframe id='{0}' src='{1}'></iframe>", name, url); | |
setTimeout(scope(checkframe, self), interval); | |
break; | |
case protocols.foreverframe: | |
transport = document.createElement("iframe"); | |
transport.style.display = "none"; | |
transport.src = url; | |
transport.onload = scope(self.close, self); | |
document.body.appendChild(transport); | |
break; | |
case protocols.serversent: | |
transport = new EventSource(url); | |
transport.addEventListener("message", function (response) { | |
var msg = JSON(response.data); | |
self.onmessage(msg); | |
}); | |
break; | |
} | |
}; | |
this.onclose = function () { }; | |
this.onmessage = function (msg) { }; | |
this.open = function (uri) { | |
url = uri; | |
setTimeout(function () { _open(url); }, 10); | |
}; | |
this.close = function () { | |
if (!active) return; | |
active = false; | |
switch (protocol) { | |
case protocols.httpstreaming: | |
if (transport.readyState != 4) transport.abort(); | |
break; | |
case protocols.ieforeverframe: | |
transport.body.removeChild(transport.getElementById(name)); | |
transport.parentWindow.push = null; | |
CollectGarbage(); | |
break; | |
case protocols.foreverframe: | |
transport.src = 'about:blank'; | |
document.body.removeChild(transport); | |
break; | |
case protocols.serversent: | |
transport.close(); | |
break; | |
} | |
transport = null; | |
self.onclose(); | |
} | |
}; | |
$(window).bind("beforeunload", function () { | |
for (var key in hubconnections) | |
hubconnections[key].close(); | |
hubconnections = {}; | |
}); | |
} (PSERVICEBUS)); | |
(function (fn) { | |
var endpointAddress = "http://localhost:8087/ESBRestService/", | |
websocketAddress = "", | |
websocketPort = "8081", | |
rethrow = false, | |
apikey = "demo", | |
passcode = "demo", | |
includeIdentity = false, | |
usernamecookie = "pservicebus_username", | |
apikeytoken = "pservicebus_apikey_key", | |
passcodetoken = "pservicebus_passcode_key", | |
username = "", | |
durable = false, | |
handlers = {}, | |
longpolling = false, | |
getcookie = function (c_name) { | |
var i, x, y, ARRcookies = document.cookie.split(";"); | |
for (i = 0; i < ARRcookies.length; i++) { | |
x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("=")); | |
y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1); | |
x = x.replace(/^\s+|\s+$/g, ""); | |
if (x == c_name) { | |
return unescape(y); | |
} | |
} | |
}, | |
setcookie = function (c_name, value, exdays) { | |
var exdate = new Date(); | |
exdate.setDate(exdate.getDate() + exdays); | |
var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString()); | |
document.cookie = c_name + "=" + c_value; | |
}, | |
getusername = function () { | |
if (username) return username; | |
username = getcookie(usernamecookie); | |
if (!username) | |
username = String.format("js{0}{1}{2}", date.getTime(), date.getMonth(), date.getFullYear()); | |
if (durable) setcookie(usernamecookie, username, 30); | |
return username; | |
}; | |
invalidstate = 1; | |
fn.ondisconnect = function () { }; | |
fn.onconnect = function () { }; | |
fn.connected = true; | |
fn.transport = { | |
msmq: 0, | |
rabbitmq: 1, | |
ravendb: 2, | |
tcp: 3, | |
redis: 7 | |
} | |
fn.format = { | |
json: 1 | |
}; | |
fn.timespan = function (day, hour, min, sec, ms) { | |
sec = sec || 0; | |
ms = ms || 0; | |
min = min || 0; | |
hour = hour || 0; | |
day = day || 0; | |
var date = new Date(); | |
date.setDate(date.getDate() + day); | |
date.setMinutes(date.getMinutes() + min); | |
date.setSeconds(date.getSeconds() + sec); | |
date.setMilliseconds(date.getMilliseconds() + ms); | |
date.setHours(date.getHours() + hour); | |
return date.getTime() - (new Date().getTime()); | |
}; | |
var ajax = (function () { | |
return { | |
helper: (function () { | |
var usejsonp = false, | |
fail = function (e) { | |
if (typeof (e) !== "string") return; | |
throw e; | |
}, self = this; | |
return { | |
jsonp: function (method, data, success) { | |
fn.connected = !(method === "Disconnect"); | |
data.ReThrowException = rethrow.toString(); | |
data.ESBUserName = apikey; | |
data.ESBPassword = passcode; | |
var url = String.format("{0}{1}?callback=?", endpointAddress, method); | |
$.ajax({ | |
url: url, | |
data: data, | |
dataType: 'jsonp', | |
crossDomain: true, | |
contentType: 'application/json; charset=utf-8', | |
success: function (result) { | |
if (success) success(result); | |
}, | |
error: function (e) { | |
if (fail) fail(e); | |
} | |
}); | |
}, | |
json: function (method, data, success, async) { | |
fn.connected = !(method === "Disconnect"); | |
async = async || false; | |
var url = String.format("{0}{1}?ReThrowException={2}&ESBUserName={3}&ESBPassword={4}", | |
endpointAddress, method, rethrow, apikey, passcode); | |
$.ajax({ | |
type: 'POST', | |
url: url, | |
data: data, | |
traditional: true, | |
dataType: 'json', | |
async: async, | |
success: function (result, status, xhr) { | |
if (result) { | |
var d = result.d || result; | |
if (d) { | |
var evald = JSON.parse(d); | |
if (success) success(evald); | |
} | |
} | |
}, | |
error: function (xhr, e, msg) { | |
if (!usejsonp) { | |
usejsonp = true; | |
self.ajaxJsonp(method, data, success); | |
return; | |
} | |
if (fail) fail(xhr.responseText); | |
} | |
}); | |
} | |
}; | |
})() | |
}; | |
})(); | |
var messagehandler = function (username, _transport, _dto, _interval, _batchsize, _action) { | |
var subscriber = username, | |
transport = _transport, | |
dto = _dto, | |
interval = _interval, | |
batchsize = _batchsize, | |
action = _action, | |
handle = null, | |
hub = null, | |
websocket = null, | |
running = false, | |
self = this, | |
xhr = null, | |
huburl = (endpointAddress + String.format("StreamSubscriberMessages/?subscriberName={0}&transportName={1}&messageTypeInfo={2}&batchSize={3}&interval={4}", | |
subscriber, transport, JSON.stringify(dto), batchsize, interval)), | |
handlemessage = function () { | |
if (!running) return; | |
handle = clearInterval(handle); | |
xhr = ajax.helper.json("GetSubscriberMessages", | |
{ subscriberName: subscriber, transportName: transport, | |
messageTypeInfo: JSON.stringify(dto), | |
batchSize: batchsize | |
}, function (msgs) { | |
for (var i = 0; i < msgs.length; i++) action(msgs[i]); | |
handle = setInterval(handlemessage, interval); | |
}); | |
}; | |
this.start = function () { | |
if (running) return; | |
running = true; | |
if ("WebSocket" in window) { | |
websocket = new websocket(fn.setting.websocket()); | |
websocket.onopen = function () { | |
websocket.send(JSON.stringify({ SubscriberName: subscriber, TransportName: transport, | |
BatchSize: batchsize, MessageTypeInfo: JSON.stringify(dto), Interval: interval | |
})); | |
}; | |
websocket.onmessage = function (e) { | |
var msg = JSON.parse(e.data); | |
action(msg); | |
}; | |
} | |
else if (!longpolling) { | |
hub = new fn.hub(); | |
hub.onmessage = action; | |
hub.onclose = function () { /*stream closing*/ }; | |
hub.open(huburl); | |
} | |
else { | |
handle = setInterval(handlemessage, interval); | |
} | |
}; | |
this.stop = function () { | |
running = false; | |
if (longpolling) handle = clearInterval(handle); | |
try { | |
if (websocket) websocket.close(); | |
else if (hub) hub.close(); | |
else if (xhr) xhr.abort(); | |
} catch (e) { } | |
xhr = null; | |
hub = null; | |
websocket = null; | |
}; | |
}; | |
fn.setting = (function () { | |
return { | |
apikey: function (value) { apikey = value; }, | |
passcode: function (value) { passcode = value; }, | |
rethrow: function (value) { rethrow = value; }, | |
websocketport: function (port) { websocketPort = port; }, | |
endpoint: function (value) { endpointAddress = value; }, | |
includeIdentity: function (value) { includeIdentity = value; }, | |
durable: function (value) { durable = value; }, | |
longpolling: function (value) { longpolling = value; }, | |
websocket: function () { | |
if (websocketAddress) return websocketAddress; | |
var url = endpointAddress.replace("//", "\\").split("/")[0], | |
tokens = url.split(":"); | |
tokens[tokens.length - 1] = websocketPort; | |
tokens[0] = "ws"; | |
url = tokens.join(":"); | |
return url.replace("\\", "//"); | |
}, | |
transport: (function () { | |
var address = "localhost:5672&userID=guest;password=guest", | |
parseEndpoint = function (topicName, subscriberName) { | |
return address + ";queue=" + topicName + subscriberName; | |
}; | |
return { | |
address: function (value) { address = value; }, | |
type: fn.transport.rabbitmq, | |
info: function (topicName, subscriberName) { | |
switch (this.type) { | |
case fn.transport.msmq: | |
case fn.transport.rabbitmq: | |
case fn.transport.redis: | |
return { | |
Format: fn.format.json, | |
Path: parseEndpoint(topicName, subscriberName) | |
} | |
break; | |
case fn.transport.ravendb: | |
return { | |
Format: fn.format.json, | |
ConnectionString: parseEndpoint(topicName, subscriberName) | |
} | |
break; | |
case fn.transport.tcp: | |
var tokens = address.split(';'), | |
ipTokens = tokens[0].split(':'), | |
useSSL = tokens.length > 1 ? | |
(true == tokens[1]) : false, | |
ipAddress = ipTokens[0], | |
port = parseInt(ipTokens[1]); | |
return { | |
Format: fn.format.json, | |
IPAddress: ipAddress, Port: port, | |
UseSSL: useSSL | |
} | |
break; | |
} | |
} | |
} | |
})() | |
} | |
})(); | |
fn.register = function (data) { | |
if (!data.topic) | |
throw "topic need to be set for register method"; | |
ajax.helper.json("RegisterTopic", | |
{ topicData: JSON.stringify({ | |
ContractDict: (data.info || {}), | |
TopicName: data.topic, | |
TopicDescription: data.description || data.topic | |
}) | |
}); | |
}; | |
fn.unregister = function (data) { | |
} | |
fn.publish = function (data) { | |
if (!data.topic || !data.message) | |
throw "topic and message property need to be set for publish method"; | |
var message = data.message, | |
headers = data.headers || {}, | |
expiration = data.expiration || fn.timespan(30)/*30 days*/; | |
if (includeIdentity) { | |
message[apikeytoken] = apikey; | |
message[passcodetoken] = passcode; | |
} | |
ajax.helper.json("PublishTopic", | |
{ topicName: data.topic, | |
topicData: JSON.stringify({ Header: headers, ExpiresIn: expiration }), | |
publishData: JSON.stringify([message]) | |
}); | |
}; | |
fn.unsubscribe = function (data) { | |
if (!data.topic) | |
throw "topic property need to be set for unsubscribe method"; | |
var topicname = data.topic, | |
name = getusername(); | |
ajax.helper.json("UnSubscribeFrom", | |
{ subscriber: name, topicName: topicname }); | |
ajax.helper.json("DeleteTransport", | |
{ subscriber: name, transportName: topicname }); | |
if (handlers[topicname]) handlers[topicname].stop(); | |
}; | |
fn.subscribe = function (data) { | |
if (!data.topic || !data.callback) | |
throw "topic and callback property need to be set for subscribe method"; | |
if (typeof (data.callback) != "function") | |
throw "callback must be a function"; | |
var topicname = data.topic, | |
callback = data.callback, | |
username = getusername(), | |
filter = data.filter || "", | |
batchsize = data.batchsize || 1, | |
contract = {}, | |
interval = data.interval || fn.timespan(0, 0, 0, 0, 500) /*500 millisecond*/, | |
handler; | |
ajax.helper.json("SelectTopic", { name: topicname }, function (t) { | |
contract = t.ContractDict; | |
ajax.helper.json("SelectSubscriber", { name: username }, function (s) { | |
var filters = filter.split(','), | |
topics = s.Topics, | |
transports = s.Transports, | |
state = s.State, | |
actions = [], i; | |
if (includeIdentity) { | |
filters.push(String.format(" {0} = {1}", apikeytoken, apikey)); | |
filters.push(String.format(" {0} = {1}", passcodetoken, passcode)); | |
} | |
filter = filters.join(","); | |
if (state == invalidstate) | |
actions.push(function () { | |
ajax.helper.json("CreateSubscriber", { subscriber: username }); | |
}); | |
if (!topics[topicname]) { | |
actions.push(function () { | |
ajax.helper.json("SubscribeTo", | |
{ subscriber: username, topicName: topicname, filter: filter }); | |
}); | |
actions.push(function () { | |
ajax.helper.json("AddTransport", | |
{ subscriber: username, transportName: topicname, | |
transportType: fn.transport.type, | |
transportData: | |
JSON.stringify(fn.transport.info(topicname, username)), | |
topicName: topicname | |
}); | |
}); | |
} | |
for (i = 0; i < actions.length; i++) actions[i](); | |
if (includeIdentity) { | |
contract[apikeytoken] = ""; | |
contract[passcodetoken] = ""; | |
} | |
handler = new messagehandler(username, topicname, contract, interval, 1, callback); | |
handler.start(); | |
handlers[topicname] = handler; | |
}); | |
}); | |
} | |
$(window).bind("beforeunload", function () { | |
if (!durable) | |
ajax.helper.json("DeleteSubscriber", { name: getusername() }); | |
}); | |
} (PSERVICEBUS)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment