Commit 9a28779f authored by Constantin Jucovschi's avatar Constantin Jucovschi
Browse files

added sally clients js code.

parent b2ed05cc
......@@ -40,6 +40,7 @@ public class ServletImpl implements SallyServlet {
CamelHttpTransportServlet srvlet = new CamelHttpTransportServlet();
httpSevlet.registerServlet("/sally", srvlet, null, null);
httpSevlet.registerResources("/sally/jobad", "/app/jobad", null);
httpSevlet.registerResources("/sally/client", "/app/client", null);
ServletComponent servletComponent = new ServletComponent();
servletComponent.setServletName(srvlet.getServletName());
camelContextProvider.registerGlobalComponent("sallyservlet", servletComponent);
......
This diff is collapsed.
This diff is collapsed.
define (require) ->
require "stomp"
xml2json = require "xml2json"
createRegisterDocument = (docQueue, envid, interfaces) ->
{
"registerdocument" :
"@xmlns" : "http://kwarc.info/sally/comm/core"
"documentqueue" : docQueue,
"environmentid" : envid,
"interfaces" : interfaces
}
connections = {};
class SallyClient
constructor : (@config, @msgHandler) ->
if connections[config.stompUrl]?
@stompClient = connections[config.stompUrl]
else
@stompClient = Stomp.client(config.stompUrl)
connections[config.stompUrl] = @stompClient
@stompClient.connect(config.stompUser, config.stompPassword, ((frame) ->
jQuery(@stompClient.connection_div).trigger("onConnected");
).bind(@))
registerDocument : (interfaces, envid, callback) =>
msg = createRegisterDocument(@privateQueue, envid, interfaces)
@send("/queue/sally_register", msg, (msg) =>
@sally_queue = msg["registerdocumentresponse"]["sallyqueue"];
callback();
)
connect : (@interfaces, envid, callback) ->
client = @stompClient
if client.connected
return callback();
if not client.connection_div?
client.connection_div = jQuery("<div>")
jQuery(client.connection_div).bind("onConnected", (e) =>
@privateQueue = "editor_tools_"+Math.floor(Math.random()*100000);
@stompClient.subscribe("/queue/"+@privateQueue, @stompMsgHandler)
@registerDocument(@interfaces, envid, callback)
)
sendSally : (msg, callback, headers) ->
@send(@sally_queue, msg, callback, headers)
send : (destination, msg, callback, headers) ->
console.log(msg);
if typeof msg == "object"
msg = xml2json.json2xml(msg)
if callback?
corrid = Math.random();
queue_post = "/temp-queue/editor_exchange"+corrid;
sub = @stompClient.subscribe(queue_post, (msg) =>
body = xml2json.xml2json(msg.body)
if (not body.html?) and callback(body, msg) == true
return;
@stompClient.unsubscribe(corrid);
, {"id" : corrid})
headers ?= {};
headers["reply-to"] = queue_post;
headers["correlation-id"] = corrid;
console.log("sending to ", destination, " msg ", msg)
@stompClient.send(destination, headers, msg.toString())
stompMsgHandler : (msg) =>
body = xml2json.xml2json(msg.body)
if body["heartbeatrequest"]? and body["heartbeatrequest"]["@xmlns"] == "http://kwarc.info/sally/comm/core"
@send(msg.headers["reply-to"], {"heartbeatresponse" : {"@xmlns" : "http://kwarc.info/sally/comm/core"}}, null,
{"correlation-id" : msg.headers["correlation-id"]})
return;
@msgHandler(body, msg, (sendBack) =>
@send(msg.headers["reply-to"], sendBack, null,
{"correlation-id" : msg.headers["correlation-id"]})
);
// Generated by CoffeeScript 1.6.3
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
define(function(require) {
var SallyClient, connections, createRegisterDocument, xml2json;
require("stomp");
xml2json = require("xml2json");
createRegisterDocument = function(docQueue, envid, interfaces) {
return {
"registerdocument": {
"@xmlns": "http://kwarc.info/sally/comm/core",
"documentqueue": docQueue,
"environmentid": envid,
"interfaces": interfaces
}
};
};
connections = {};
return SallyClient = (function() {
function SallyClient(config, msgHandler) {
this.config = config;
this.msgHandler = msgHandler;
this.stompMsgHandler = __bind(this.stompMsgHandler, this);
this.registerDocument = __bind(this.registerDocument, this);
if (connections[config.stompUrl] != null) {
this.stompClient = connections[config.stompUrl];
} else {
this.stompClient = Stomp.client(config.stompUrl);
connections[config.stompUrl] = this.stompClient;
this.stompClient.connect(config.stompUser, config.stompPassword, (function(frame) {
return jQuery(this.stompClient.connection_div).trigger("onConnected");
}).bind(this));
}
}
SallyClient.prototype.registerDocument = function(interfaces, envid, callback) {
var msg,
_this = this;
msg = createRegisterDocument(this.privateQueue, envid, interfaces);
return this.send("/queue/sally_register", msg, function(msg) {
_this.sally_queue = msg["registerdocumentresponse"]["sallyqueue"];
return callback();
});
};
SallyClient.prototype.connect = function(interfaces, envid, callback) {
var client,
_this = this;
this.interfaces = interfaces;
client = this.stompClient;
if (client.connected) {
return callback();
}
if (client.connection_div == null) {
client.connection_div = jQuery("<div>");
}
return jQuery(client.connection_div).bind("onConnected", function(e) {
_this.privateQueue = "editor_tools_" + Math.floor(Math.random() * 100000);
_this.stompClient.subscribe("/queue/" + _this.privateQueue, _this.stompMsgHandler);
return _this.registerDocument(_this.interfaces, envid, callback);
});
};
SallyClient.prototype.sendSally = function(msg, callback, headers) {
return this.send(this.sally_queue, msg, callback, headers);
};
SallyClient.prototype.send = function(destination, msg, callback, headers) {
var corrid, queue_post, sub,
_this = this;
console.log(msg);
if (typeof msg === "object") {
msg = xml2json.json2xml(msg);
}
if (callback != null) {
corrid = Math.random();
queue_post = "/temp-queue/editor_exchange" + corrid;
sub = this.stompClient.subscribe(queue_post, function(msg) {
var body;
body = xml2json.xml2json(msg.body);
if ((body.html == null) && callback(body, msg) === true) {
return;
}
return _this.stompClient.unsubscribe(corrid);
}, {
"id": corrid
});
if (headers == null) {
headers = {};
}
headers["reply-to"] = queue_post;
headers["correlation-id"] = corrid;
}
console.log("sending to ", destination, " msg ", msg);
return this.stompClient.send(destination, headers, msg.toString());
};
SallyClient.prototype.stompMsgHandler = function(msg) {
var body,
_this = this;
body = xml2json.xml2json(msg.body);
if ((body["heartbeatrequest"] != null) && body["heartbeatrequest"]["@xmlns"] === "http://kwarc.info/sally/comm/core") {
this.send(msg.headers["reply-to"], {
"heartbeatresponse": {
"@xmlns": "http://kwarc.info/sally/comm/core"
}
}, null, {
"correlation-id": msg.headers["correlation-id"]
});
return;
}
return this.msgHandler(body, msg, function(sendBack) {
return _this.send(msg.headers["reply-to"], sendBack, null, {
"correlation-id": msg.headers["correlation-id"]
});
});
};
return SallyClient;
})();
});
// Generated by CoffeeScript 1.3.3
(function() {
var Byte, Client, Frame, Stomp,
__hasProp = {}.hasOwnProperty;
Byte = {
LF: '\x0A',
NULL: '\x00'
};
Frame = (function() {
function Frame(command, headers, body) {
this.command = command;
this.headers = headers != null ? headers : {};
this.body = body != null ? body : '';
}
Frame.prototype.toString = function() {
var lines, name, value, _ref;
lines = [this.command];
_ref = this.headers;
for (name in _ref) {
if (!__hasProp.call(_ref, name)) continue;
value = _ref[name];
lines.push("" + name + ":" + value);
}
if (this.body) {
lines.push("content-length:" + ('' + this.body).length);
}
lines.push(Byte.LF + this.body);
return lines.join(Byte.LF);
};
Frame._unmarshallSingle = function(data) {
var body, chr, command, divider, headerLines, headers, i, idx, len, line, start, trim, _i, _j, _ref, _ref1;
divider = data.search(RegExp("" + Byte.LF + Byte.LF));
headerLines = data.substring(0, divider).split(Byte.LF);
command = headerLines.shift();
headers = {};
trim = function(str) {
return str.replace(/^\s+|\s+$/g, '');
};
line = idx = null;
for (i = _i = 0, _ref = headerLines.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
line = headerLines[i];
idx = line.indexOf(':');
headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1));
}
body = '';
start = divider + 2;
if (headers['content-length']) {
len = parseInt(headers['content-length']);
body = ('' + data).substring(start, start + len);
} else {
chr = null;
for (i = _j = start, _ref1 = data.length; start <= _ref1 ? _j < _ref1 : _j > _ref1; i = start <= _ref1 ? ++_j : --_j) {
chr = data.charAt(i);
if (chr === Byte.NULL) {
break;
}
body += chr;
}
}
return new Frame(command, headers, body);
};
Frame.unmarshall = function(datas) {
var data;
return (function() {
var _i, _len, _ref, _results;
_ref = datas.split(RegExp("" + Byte.NULL + Byte.LF + "*"));
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
data = _ref[_i];
if ((data != null ? data.length : void 0) > 0) {
_results.push(Frame._unmarshallSingle(data));
}
}
return _results;
})();
};
Frame.marshall = function(command, headers, body) {
var frame;
frame = new Frame(command, headers, body);
return frame.toString() + Byte.NULL;
};
return Frame;
})();
Client = (function() {
function Client(ws) {
this.ws = ws;
this.ws.binaryType = "arraybuffer";
this.counter = 0;
this.connected = false;
this.heartbeat = {
outgoing: 10000,
incoming: 10000
};
this.subscriptions = {};
}
Client.prototype._transmit = function(command, headers, body) {
var out;
out = Frame.marshall(command, headers, body);
if (typeof this.debug === "function") {
this.debug(">>> " + out);
}
return this.ws.send(out);
};
Client.prototype._setupHeartbeat = function(headers) {
var serverIncoming, serverOutgoing, ttl, v, _ref, _ref1,
_this = this;
if ((_ref = headers.version) !== Stomp.VERSIONS.V1_1 && _ref !== Stomp.VERSIONS.V1_2) {
return;
}
_ref1 = (function() {
var _i, _len, _ref1, _results;
_ref1 = headers['heart-beat'].split(",");
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
v = _ref1[_i];
_results.push(parseInt(v));
}
return _results;
})(), serverOutgoing = _ref1[0], serverIncoming = _ref1[1];
if (!(this.heartbeat.outgoing === 0 || serverIncoming === 0)) {
ttl = Math.max(this.heartbeat.outgoing, serverIncoming);
if (typeof this.debug === "function") {
this.debug("send PING every " + ttl + "ms");
}
this.pinger = typeof window !== "undefined" && window !== null ? window.setInterval(function() {
_this.ws.send(Byte.LF);
return typeof _this.debug === "function" ? _this.debug(">>> PING") : void 0;
}, ttl) : void 0;
}
if (!(this.heartbeat.incoming === 0 || serverOutgoing === 0)) {
ttl = Math.max(this.heartbeat.incoming, serverOutgoing);
if (typeof this.debug === "function") {
this.debug("check PONG every " + ttl + "ms");
}
return this.ponger = typeof window !== "undefined" && window !== null ? window.setInterval(function() {
var delta;
delta = Date.now() - _this.serverActivity;
if (delta > ttl * 2) {
if (typeof _this.debug === "function") {
_this.debug("did not receive server activity for the last " + delta + "ms");
}
return _this._cleanUp();
}
}, ttl) : void 0;
}
};
Client.prototype.connect = function(login, passcode, connectCallback, errorCallback, vhost) {
var _this = this;
this.connectCallback = connectCallback;
if (typeof this.debug === "function") {
this.debug("Opening Web Socket...");
}
this.ws.onmessage = function(evt) {
var arr, c, data, frame, onreceive, _i, _len, _ref, _results;
data = typeof ArrayBuffer !== 'undefined' && evt.data instanceof ArrayBuffer ? (arr = new Uint8Array(evt.data), typeof _this.debug === "function" ? _this.debug("--- got data length: " + arr.length) : void 0, ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = arr.length; _i < _len; _i++) {
c = arr[_i];
_results.push(String.fromCharCode(c));
}
return _results;
})()).join('')) : evt.data;
_this.serverActivity = Date.now();
if (data === Byte.LF) {
if (typeof _this.debug === "function") {
_this.debug("<<< PONG");
}
return;
}
if (typeof _this.debug === "function") {
_this.debug("<<< " + data);
}
_ref = Frame.unmarshall(data);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
frame = _ref[_i];
switch (frame.command) {
case "CONNECTED":
if (typeof _this.debug === "function") {
_this.debug("connected to server " + frame.headers.server);
}
_this.connected = true;
_this._setupHeartbeat(frame.headers);
_results.push(typeof _this.connectCallback === "function" ? _this.connectCallback(frame) : void 0);
break;
case "MESSAGE":
onreceive = _this.subscriptions[frame.headers.subscription];
_results.push(typeof onreceive === "function" ? onreceive(frame) : void 0);
break;
case "RECEIPT":
_results.push(typeof _this.onreceipt === "function" ? _this.onreceipt(frame) : void 0);
break;
case "ERROR":
_results.push(typeof errorCallback === "function" ? errorCallback(frame) : void 0);
break;
default:
_results.push(typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0);
}
}
return _results;
};
this.ws.onclose = function() {
var msg;
msg = "Whoops! Lost connection to " + _this.ws.url;
if (typeof _this.debug === "function") {
_this.debug(msg);
}
return typeof errorCallback === "function" ? errorCallback(msg) : void 0;
};
return this.ws.onopen = function() {
var headers;
if (typeof _this.debug === "function") {
_this.debug('Web Socket Opened...');
}
headers = {
"accept-version": Stomp.VERSIONS.supportedVersions(),
"heart-beat": [_this.heartbeat.outgoing, _this.heartbeat.incoming].join(',')
};
if (vhost) {
headers.host = vhost;
}
if (login) {
headers.login = login;
}
if (passcode) {
headers.passcode = passcode;
}
return _this._transmit("CONNECT", headers);
};
};
Client.prototype.disconnect = function(disconnectCallback) {
this._transmit("DISCONNECT");
this.ws.onclose = null;
this._cleanUp();
return typeof disconnectCallback === "function" ? disconnectCallback() : void 0;
};
Client.prototype._cleanUp = function() {
this.ws.close();
this.connected = false;
if (this.pinger) {
if (typeof window !== "undefined" && window !== null) {
window.clearInterval(this.pinger);
}
}
if (this.ponger) {
return typeof window !== "undefined" && window !== null ? window.clearInterval(this.ponger) : void 0;
}
};
Client.prototype.send = function(destination, headers, body) {
if (headers == null) {
headers = {};
}
if (body == null) {
body = '';
}
headers.destination = destination;
return this._transmit("SEND", headers, body);
};
Client.prototype.subscribe = function(destination, callback, headers) {
if (headers == null) {
headers = {};
}
if (!headers.id) {
headers.id = "sub-" + this.counter++;
}
headers.destination = destination;
this.subscriptions[headers.id] = callback;
this._transmit("SUBSCRIBE", headers);
return headers.id;
};
Client.prototype.unsubscribe = function(id) {
delete this.subscriptions[id];
return this._transmit("UNSUBSCRIBE", {
id: id
});
};
Client.prototype.begin = function(transaction) {
return this._transmit("BEGIN", {
transaction: transaction
});
};
Client.prototype.commit = function(transaction) {
return this._transmit("COMMIT", {
transaction: transaction
});
};
Client.prototype.abort = function(transaction) {
return this._transmit("ABORT", {
transaction: transaction
});
};
Client.prototype.ack = function(messageID, subscription, headers) {
if (headers == null) {
headers = {};
}
headers["message-id"] = messageID;
headers.subscription = subscription;
return this._transmit("ACK", headers);
};
Client.prototype.nack = function(messageID, subscription, headers) {
if (headers == null) {
headers = {};
}
headers["message-id"] = messageID;
headers.subscription = subscription;
return this._transmit("NACK", headers);
};
return Client;
})();
Stomp = {
libVersion: "2.0.0-next",
VERSIONS: {
V1_0: '1.0',
V1_1: '1.1',
V1_2: '1.2',
supportedVersions: function() {
return '1.1,1.0';
}
},
client: function(url, protocols) {
var klass, ws;
if (protocols == null) {
protocols = ['v10.stomp', 'v11.stomp'];
}
klass = Stomp.WebSocketClass || WebSocket;
ws = new klass(url, protocols);
return new Client(ws);
},
over: function(ws) {