📄 jquery.cometd.js
字号:
function _messageSuccess(message) { if (message.successful === undefined) { if (message.data) { // It is a plain message, and not a bayeux meta message _notifyListeners(message.channel, message); } else { _debug('Unknown message {}', JSON.stringify(message)); } } else { if (message.successful) { _debug('Publish successful'); _notifyListeners('/meta/publish', message); } else { _debug('Publish unsuccessful'); _notifyListeners('/meta/publish', message); _notifyListeners('/meta/unsuccessful', message); } } }; function _messageFailure(xhr, message) { _debug('Publish failure'); var failureMessage = { successful: false, failure: true, channel: message.channel, request: message, xhr: xhr, advice: { action: 'none', interval: 0 } }; _notifyListeners('/meta/publish', failureMessage); _notifyListeners('/meta/unsuccessful', failureMessage); }; function _notifyListeners(channel, message) { // Notify direct listeners _notify(channel, message); // Notify the globbing listeners var channelParts = channel.split("/"); var last = channelParts.length - 1; for (var i = last; i > 0; --i) { var channelPart = channelParts.slice(0, i).join('/') + '/*'; // We don't want to notify /foo/* if the channel is /foo/bar/baz, // so we stop at the first non recursive globbing if (i == last) _notify(channelPart, message); // Add the recursive globber and notify channelPart += '*'; _notify(channelPart, message); } }; function _notify(channel, message) { var subscriptions = _listeners[channel]; if (subscriptions && subscriptions.length > 0) { $.each(subscriptions, function(index, subscription) { // Subscriptions may come and go, so the array may have 'holes' if (subscription) { try { _debug('Notifying subscription: channel \'{}\', callback \'{}\'', channel, subscription.callback.name); subscription.callback.call(subscription.scope, message); } catch (x) { // Ignore exceptions from callbacks _warn('Exception during execution of callback \'{}\' on channel \'{}\' for message {}, exception: {}', subscription.callback.name, channel, JSON.stringify(message), x); } } }); } }; function _resetBackoff() { _backoff = 0; }; function _increaseBackoff() { if (_backoff < _maxBackoff) _backoff += _backoffIncrement; }; var _error = this._error = function(text, args) { _log('error', _format.apply(this, arguments)); }; var _warn = this._warn = function(text, args) { _log('warn', _format.apply(this, arguments)); }; var _info = this._info = function(text, args) { _log('info', _format.apply(this, arguments)); }; var _debug = this._debug = function(text, args) { _log('debug', _format.apply(this, arguments)); }; function _log(level, text) { var priority = _logPriorities[level]; var configPriority = _logPriorities[_logLevel]; if (!configPriority) configPriority = _logPriorities['info']; if (priority >= configPriority) { if (window.console) window.console.log(text); } }; function _format(text) { var braces = /\{\}/g; var result = ''; var start = 0; var count = 0; while (braces.test(text)) { result += text.substr(start, braces.lastIndex - start - 2); var arg = arguments[++count]; result += arg !== undefined ? arg : '{}'; start = braces.lastIndex; } result += text.substr(start, text.length - start); return result; }; function newLongPollingTransport() { return $.extend({}, new Transport('long-polling'), new LongPollingTransport()); }; function newCallbackPollingTransport() { return $.extend({}, new Transport('callback-polling'), new CallbackPollingTransport()); }; /** * Base object with the common functionality for transports. * The key responsibility is to allow at most 2 outstanding requests to the server, * to avoid that requests are sent behind a long poll. * To achieve this, we have one reserved request for the long poll, and all other * requests are serialized one after the other. */ var Transport = function(type) { var _maxRequests = 2; var _requestIds = 0; var _cometRequest = null; var _requests = []; var _packets = []; this.getType = function() { return type; }; this.send = function(packet, comet) { if (comet) _cometSend(this, packet); else _send(this, packet); }; function _cometSend(self, packet) { if (_cometRequest !== null) throw 'Concurrent comet requests not allowed, request ' + _cometRequest.id + ' not yet completed'; var requestId = ++_requestIds; _debug('Beginning comet request {}', requestId); var request = {id: requestId}; self.deliver(packet, request); _cometRequest = request; }; function _send(self, packet) { var requestId = ++_requestIds; _debug('Beginning request {}, {} other requests, {} queued requests', requestId, _requests.length, _packets.length); var request = {id: requestId}; // Consider the comet request which should always be present if (_requests.length < _maxRequests - 1) { _debug('Delivering request {}', requestId); self.deliver(packet, request); _requests.push(request); } else { _packets.push([packet, request]); _debug('Queued request {}, {} queued requests', requestId, _packets.length); } }; this.complete = function(request, success, comet) { if (comet) _cometComplete(request); else _complete(this, request, success); }; function _cometComplete(request) { var requestId = request.id; if (_cometRequest !== request) throw 'Comet request mismatch, completing request ' + requestId; // Reset comet request _cometRequest = null; _debug('Ended comet request {}', requestId); }; function _complete(self, request, success) { var requestId = request.id; var index = $.inArray(request, _requests); // The index can be negative the request has been aborted if (index >= 0) _requests.splice(index, 1); _debug('Ended request {}, {} other requests, {} queued requests', requestId, _requests.length, _packets.length); if (_packets.length > 0) { var packet = _packets.shift(); if (success) { _debug('Dequeueing and sending request {}, {} queued requests', packet[1].id, _packets.length); _send(self, packet[0]); } else { _debug('Dequeueing and failing request {}, {} queued requests', packet[1].id, _packets.length); packet[0].onFailure(packet[1], 'error'); } } }; this.abort = function() { $.each(_requests, function(index, request) { _debug('Aborting request {}', request.id); if (request.xhr) request.xhr.abort(); }); if (_cometRequest) { _debug('Aborting comet request {}', _cometRequest.id); if (_cometRequest.xhr) _cometRequest.xhr.abort(); } _cometRequest = null; _requests = []; _packets = []; }; }; var LongPollingTransport = function() { this.deliver = function(packet, request) { request.xhr = $.ajax({ url: packet.url, type: 'POST', contentType: 'text/json;charset=UTF-8', beforeSend: function(xhr) { xhr.setRequestHeader('Connection', 'Keep-Alive'); return true; }, data: JSON.stringify(packet.messages), success: function(response) { packet.onSuccess(request, response); }, error: function(xhr, reason, exception) { packet.onFailure(request, reason, exception); } }); }; }; var CallbackPollingTransport = function() { var _maxLength = 2000; this.deliver = function(packet, request) { // Microsoft Internet Explorer has a 2083 URL max length // We must ensure that we stay within that length var messages = JSON.stringify(packet.messages); // Encode the messages because all brackets, quotes, commas, colons, etc // present in the JSON will be URL encoded, taking many more characters var urlLength = packet.url.length + encodeURI(messages).length; _debug('URL length: {}', urlLength); // Let's stay on the safe side and use 2000 instead of 2083 // also because we did not count few characters among which // the parameter name 'message' and the parameter 'jsonp', // which sum up to about 50 chars if (urlLength > _maxLength) { var x = packet.messages.length > 1 ? 'Too many bayeux messages in the same batch resulting in message too big ' + '(' + urlLength + ' bytes, max is ' + _maxLength + ') for transport ' + this.getType() : 'Bayeux message too big (' + urlLength + ' bytes, max is ' + _maxLength + ') ' + 'for transport ' + this.getType(); // Keep the semantic of calling response callbacks asynchronously after the request _setTimeout(function() { packet.onFailure(request, 'error', x); }, 0); } else { $.ajax({ url: packet.url, type: 'GET', dataType: 'jsonp', jsonp: 'jsonp', beforeSend: function(xhr) { xhr.setRequestHeader('Connection', 'Keep-Alive'); return true; }, data: { // In callback-polling, the content must be sent via the 'message' parameter message: messages }, success: function(response) { packet.onSuccess(request, response); }, error: function(xhr, reason, exception) { packet.onFailure(request, reason, exception); } }); } }; }; }; /** * The JS object that exposes the comet API to applications */ $.cometd = new $.Cometd(); // The default instance})(jQuery);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -