stompjs
Version:
STOMP for JavaScript apps (Web browser & node.js)
198 lines (171 loc) • 5.43 kB
JavaScript
// (c) 2010 Jeff Mesnil -- http://jmesnil.net/
// Copyright (C) FuseSource, Inc. -- http://fusesource.com
(function(window) {
var Stomp = {};
Stomp.frame = function(command, headers, body) {
return {
command: command,
headers: headers,
body: body,
toString: function() {
var out = command + '\n';
if (headers) {
for (header in headers) {
if(headers.hasOwnProperty(header)) {
out = out + header + ': ' + headers[header] + '\n';
}
}
}
out = out + '\n';
if (body) {
out = out + body;
}
return out;
}
}
};
trim = function(str) {
return str.replace(/^\s+/g,'').replace(/\s+$/g,'');
};
Stomp.unmarshal = function(data) {
var divider = data.search(/\n\n/),
headerLines = data.substring(0, divider).split('\n'),
command = headerLines.shift(),
headers = {},
body = '';
// Parse headers
var line = idx = null;
for (var i = 0; i < headerLines.length; i++) {
line = headerLines[i];
idx = line.indexOf(':');
headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1));
}
// Parse body, stopping at the first \0 found.
// TODO: Add support for content-length header.
var chr = null;
for (var i = divider + 2; i < data.length; i++) {
chr = data.charAt(i);
if (chr === '\0') {
break;
}
body += chr;
}
return Stomp.frame(command, headers, body);
};
Stomp.marshal = function(command, headers, body) {
return Stomp.frame(command, headers, body).toString() + '\0';
};
Stomp.client = function (url){
var that, ws, login, passcode;
var counter = 0; // used to index subscribers
// subscription callbacks indexed by subscriber's ID
var subscriptions = {};
debug = function(str) {
if (that.debug) {
that.debug(str);
}
};
onmessage = function(evt) {
var data = evt.data
if (data instanceof ArrayBuffer) {
view = new Uint8Array(data);
data = "";
var i, len;
for (i = 0, len = view.length; i < len; i++) {
data += String.fromCharCode(view[i]);
}
}
debug('<<< ' + data);
var frame = Stomp.unmarshal(data);
if (frame.command === "CONNECTED" && that.connectCallback) {
that.connectCallback(frame);
} else if (frame.command === "MESSAGE") {
var onreceive = subscriptions[frame.headers.subscription];
if (onreceive) {
onreceive(frame);
}
} else if (frame.command === "RECEIPT" && that.onreceipt) {
that.onreceipt(frame);
} else if (frame.command === "ERROR" && that.onerror) {
that.onerror(frame);
}
};
transmit = function(command, headers, body) {
var out = Stomp.marshal(command, headers, body);
debug(">>> " + out);
ws.send(out);
};
that = {};
that.connect = function(login_, passcode_, connectCallback, errorCallback) {
debug("Opening Web Socket...");
var Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket;
ws = new Socket(url);
ws.binaryType = "arraybuffer";
ws.onmessage = onmessage;
ws.onclose = function() {
var msg = "Whoops! Lost connection to " + url;
debug(msg);
if (errorCallback) {
errorCallback(msg);
}
};
ws.onopen = function() {
debug('Web Socket Opened...');
transmit("CONNECT", {login: login, passcode: passcode});
// connectCallback handler will be called from onmessage when a CONNECTED frame is received
};
login = login_;
passcode = passcode_;
that.connectCallback = connectCallback;
};
that.disconnect = function(disconnectCallback) {
transmit("DISCONNECT");
ws.close();
if (disconnectCallback) {
disconnectCallback();
}
};
that.send = function(destination, headers, body) {
var headers = headers || {};
headers.destination = destination;
transmit("SEND", headers, body);
};
that.subscribe = function(destination, callback, headers) {
var headers = headers || {};
var id = "sub-" + counter++;
headers.destination = destination;
headers.id = id;
subscriptions[id] = callback;
transmit("SUBSCRIBE", headers);
return id;
};
that.unsubscribe = function(id, headers) {
var headers = headers || {};
headers.id = id;
delete subscriptions[id];
transmit("UNSUBSCRIBE", headers);
};
that.begin = function(transaction, headers) {
var headers = headers || {};
headers.transaction = transaction;
transmit("BEGIN", headers);
};
that.commit = function(transaction, headers) {
var headers = headers || {};
headers.transaction = transaction;
transmit("COMMIT", headers);
};
that.abort = function(transaction, headers) {
var headers = headers || {};
headers.transaction = transaction;
transmit("ABORT", headers);
};
that.ack = function(message_id, headers) {
var headers = headers || {};
headers["message-id"] = message_id;
transmit("ACK", headers);
};
return that;
};
window.Stomp = Stomp;
})(window);