/Prototypes/Client2/message-queue.js
JavaScript | 115 lines | 93 code | 8 blank | 14 comment | 18 complexity | e236c59591d258a76805ebb5aa9502e9 MD5 | raw file
- // message-queue.js
- // a message queuing service for the UConnocalypse client
- //
- // This library provides a simple message queue that supports continuations on
- // receiving confirmations for sent messages. Basically, when a message is
- // sent, a handler is returned that can be used to attach callbacks that are
- // called when the message's response is received for the server.
- //
- // For documentation on using this library, see the project's wiki at:
- // https://bitbucket.org/EthanLevine/senior-design/wiki/message-queue.js
- var messageQueue = (function () {
- "use strict";
- var onMessageReceive = function (mq, messageData) {
- var handler, cb;
- if (messageData[0] === "confirm") {
- handler = mq.callbackQueue.shift();
- cb = handler.confirmCallback;
- if (typeof cb === "function") {
- cb.apply(messageData, messageData.slice(2));
- }
- } else if (messageData[0] === "error") {
- handler = mq.callbackQueue.shift();
- cb = handler.errorCallbacks[messageData[1]];
- if (typeof cb === "function") {
- cb.apply(messageData, messageData.slice(1));
- } else {
- // try general error handler for this message
- cb = handler.errorGeneralCallback;
- if (typeof cb === "function") {
- cb.apply(messageData, messageData.slice(1));
- } else {
- // call the uncaught error handler.
- cb = mq.uncaughtErrorCallback;
- cb.apply(messageData, messageData.slice(1));
- }
- }
- } else {
- // neither confirm nor error - must be passed to mq's
- // general handler.
- cb = mq.generalCallback;
- cb(messageData);
- }
- };
- var MessageQueueHandler = function () {
- this.confirmCallback = null;
- this.errorCallbacks = {};
- this.errorGeneralCallback = null;
- };
- MessageQueueHandler.prototype = {};
- MessageQueueHandler.prototype.onconfirm = function (callback) {
- this.confirmCallback = callback;
- return this;
- };
- MessageQueueHandler.prototype.onerror = function (callback, errorCode) {
- if (typeof errorCode === "undefined") {
- this.errorGeneralCallback = callback;
- } else {
- this.errorCallbacks[errorCode] = callback;
- }
- return this;
- };
- var MessageQueue = function (socket, generalCallback, uncaughtErrorCallback) {
- this.ws = socket;
- this.callbackQueue = [];
- this.generalCallback = generalCallback;
- this.uncaughtErrorCallback = uncaughtErrorCallback;
- this.queuedMessages = [];
- var thisMessageQueue = this;
- this.ws.onmessage = function (event) {
- onMessageReceive(thisMessageQueue, JSON.parse(event.data));
- };
- this.ws.onopen = function (event) {
- while (thisMessageQueue.queuedMessages.length > 0) {
- thisMessageQueue.ws.send(JSON.stringify(thisMessageQueue.queuedMessages.shift()));
- }
- };
- this.ws.onerror = function (event) {
- thisMessageQueue.uncaughtErrorCallback(3, "An error occurred with the underlying websocket.");
- };
- };
- MessageQueue.prototype = {};
- MessageQueue.prototype.send = function (messageData) {
- var cbo = new MessageQueueHandler();
- this.callbackQueue.push(cbo);
- if (this.ws.readyState === 0) {
- this.uncaughtErrorCallback("Not yet connected to server");
- }
- else if(this.ws.readyState === 3){
- this.uncaughtErrorCallback("Couldn't Connect to WebSocket");
- }
- else {
- this.ws.send(JSON.stringify(messageData));
- }
- return cbo;
- };
- return {
- create: function (serverAddress, generalCallback, uncaughtErrorCallback) {
- if (typeof generalCallback !== "function") {
- generalCallback = function () {};
- }
- if (typeof uncaughtErrorCallback !== "function") {
- uncaughtErrorCallback = function () {};
- }
- return new MessageQueue(new WebSocket(serverAddress), generalCallback, uncaughtErrorCallback);
- }
- };
- })();