/** * AJAX long polling library. * * @author ajanata */ cah.longpoll = {}; cah.longpoll.TIMEOUT = 2 * 60 * 1000; // cah.longpoll.TIMEOUT = 30 * 1000; /** * Backoff when there was an error. * * @type {number} */ cah.longpoll.INITIAL_BACKOFF = 500; /** * Backoff after a successful request. * * @type {number} */ cah.longpoll.NORMAL_BACKOFF = 1; cah.longpoll.Backoff = cah.longpoll.INITIAL_BACKOFF; cah.longpoll.Resume = true; cah.longpoll.ErrorCodeHandlers = {}; cah.longpoll.EventHandlers = {}; cah.longpoll.longPoll = function() { cah.log.debug("starting long poll"); $.ajax({ complete : cah.longpoll.complete, error : cah.longpoll.error, success : cah.longpoll.done, timeout : cah.longpoll.TIMEOUT, url : cah.LONGPOLL_URI, }); }; cah.longpoll.complete = function() { if (cah.longpoll.Resume) { setTimeout("cah.longpoll.longPoll()", cah.longpoll.Backoff); } }; cah.longpoll.done = function(data_list) { cah.log.debug("long poll done", data_list); var data_list_work; // we need to handle non-array data, too, so just make it look like an array if (data_list[cah.$.LongPollResponse.TIMESTAMP] || data_list[cah.$.LongPollResponse.ERROR]) { data_list_work = {}; data_list_work[0] = data_list; } else { data_list_work = data_list; } for ( var index in data_list_work) { var data = data_list_work[index]; if (data[cah.$.LongPollResponse.ERROR]) { // TODO cancel any timers or whatever we may have, and disable interface // this probably should be done in the appropriate error code handler because we may not // want to always be that extreme. var errorCode = data[cah.$.LongPollResponse.ERROR_CODE]; if (cah.longpoll.ErrorCodeHandlers[errorCode]) { cah.longpoll.ErrorCodeHandlers[errorCode](data); } else { cah.log.error(cah.$.ErrorCode_msg[errorCode]); } } else { var event = data[cah.$.LongPollResponse.EVENT]; if (cah.longpoll.EventHandlers[event]) { cah.longpoll.EventHandlers[event](data); } else { cah.log.error("Unhandled event " + event); } } } // reset the backoff to normal when there's a successful operation cah.longpoll.Backoff = cah.longpoll.NORMAL_BACKOFF; }; cah.longpoll.error = function(jqXHR, textStatus, errorThrown) { // TODO deal with this somehow cah.log.debug(textStatus); if (cah.longpoll.Backoff < cah.longpoll.INITIAL_BACKOFF) { cah.longpoll.Backoff = cah.longpoll.INITIAL_BACKOFF; } else { cah.longpoll.Backoff *= 2; } cah.log .error("Error communicating with server. Will try again in " + (cah.longpoll.Backoff / 1000) + " second" + (cah.longpoll.Backoff != 1000 ? "s" : "") + "."); };