📄 jquery.cometd.js
字号:
* Both properties are optional, but if they are present they will be called * respectively for each incoming message and for each outgoing message. * </pre> * @param name the name of the extension * @param extension the extension to register * @return true if the extension was registered, false otherwise * @see #unregisterExtension(name) */ this.registerExtension = function(name, extension) { var existing = false; $.each(_extensions, function(index, extension) { if (extension.name == name) { existing = true; return false; } }); if (!existing) { _extensions.push({ name: name, extension: extension }); _debug('Registered extension \'{}\'', name); return true; } else { _info('Could not register extension with name \'{}\': another extension with the same name already exists'); return false; } }; /** * Unregister an extension previously registered with * {@link #registerExtension(name, extension)}. * @param name the name of the extension to unregister. * @return true if the extension was unregistered, false otherwise */ this.unregisterExtension = function(name) { var unregistered = false; $.each(_extensions, function(index, extension) { if (extension.name == name) { _extensions.splice(index, 1); unregistered = true; _debug('Unregistered extension \'{}\'', name); return false; } }); return unregistered; }; /** * Starts a the batch of messages to be sent in a single request. * @see _endBatch(deliverMessages) */ function _startBatch() { ++_batch; }; /** * Ends the batch of messages to be sent in a single request, * optionally delivering messages present in the message queue depending * on the given argument. * @param deliverMessages whether to deliver the messages in the queue or not * @see _startBatch() */ function _endBatch(deliverMessages) { --_batch; if (_batch < 0) _batch = 0; if (deliverMessages && _batch == 0 && !_isDisconnected()) { var messages = _messageQueue; _messageQueue = []; if (messages.length > 0) _deliver(messages, false); } }; function _nextMessageId() { return ++_messageId; }; /** * Converts the given response into an array of bayeux messages * @param response the response to convert * @return an array of bayeux messages obtained by converting the response */ function _convertToMessages(response) { if (response === undefined) return []; if (response instanceof Array) return response; if (response instanceof String || typeof response == 'string') return eval('(' + response + ')'); if (response instanceof Object) return [response]; throw 'Conversion Error ' + response + ', typeof ' + (typeof response); }; function _setStatus(newStatus) { _debug('{} -> {}', _status, newStatus); _status = newStatus; }; function _isDisconnected() { return _status == 'disconnecting' || _status == 'disconnected'; }; /** * Sends the initial handshake message */ function _handshake(handshakeProps) { _debug('Starting handshake'); _clientId = null; // Start a batch. // This is needed because handshake and connect are async. // It may happen that the application calls init() then subscribe() // and the subscribe message is sent before the connect message, if // the subscribe message is not held until the connect message is sent. // So here we start a batch to hold temporarly any message until // the connection is fully established. _batch = 0; _startBatch(); // Save the original properties provided by the user // Deep copy to avoid the user to be able to change them later _handshakeProps = $.extend(true, {}, handshakeProps); var bayeuxMessage = { version: '1.0', minimumVersion: '0.9', channel: '/meta/handshake', supportedConnectionTypes: _xd ? ['callback-polling'] : ['long-polling', 'callback-polling'] }; // Do not allow the user to mess with the required properties, // so merge first the user properties and *then* the bayeux message var message = $.extend({}, handshakeProps, bayeuxMessage); // We started a batch to hold the application messages, // so here we must bypass it and deliver immediately. _setStatus('handshaking'); _deliver([message], false); }; function _findTransport(handshakeResponse) { var transportTypes = handshakeResponse.supportedConnectionTypes; if (_xd) { // If we are cross domain, check if the server supports it, that's the only option if ($.inArray('callback-polling', transportTypes) >= 0) return _transport; } else { // Check if we can keep long-polling if ($.inArray('long-polling', transportTypes) >= 0) return _transport; // The server does not support long-polling if ($.inArray('callback-polling', transportTypes) >= 0) return newCallbackPollingTransport(); } return null; }; function _delayedHandshake() { _setStatus('handshaking'); _delayedSend(function() { _handshake(_handshakeProps); }); }; function _delayedConnect() { _setStatus('connecting'); _delayedSend(function() { _connect(); }); }; function _delayedSend(operation) { _cancelDelayedSend(); var delay = _backoff; _debug("Delayed send: backoff {}, interval {}", _backoff, _advice.interval); if (_advice.interval && _advice.interval > 0) delay += _advice.interval; _scheduledSend = _setTimeout(operation, delay); }; function _cancelDelayedSend() { if (_scheduledSend !== null) clearTimeout(_scheduledSend); _scheduledSend = null; }; function _setTimeout(funktion, delay) { return setTimeout(function() { try { funktion(); } catch (x) { _debug('Exception during scheduled execution of function \'{}\': {}', funktion.name, x); } }, delay); }; /** * Sends the connect message */ function _connect() { _debug('Starting connect'); var message = { channel: '/meta/connect', connectionType: _transport.getType() }; _setStatus('connecting'); _deliver([message], true); _setStatus('connected'); }; function _send(message) { if (_batch > 0) _messageQueue.push(message); else _deliver([message], false); }; /** * Delivers the messages to the comet server * @param messages the array of messages to send */ function _deliver(messages, comet) { // We must be sure that the messages have a clientId. // This is not guaranteed since the handshake may take time to return // (and hence the clientId is not known yet) and the application // may create other messages. $.each(messages, function(index, message) { message['id'] = _nextMessageId(); if (_clientId) message['clientId'] = _clientId; messages[index] = _applyOutgoingExtensions(message); }); var self = this; var envelope = { url: _url, messages: messages, onSuccess: function(request, response) { try { _handleSuccess.call(self, request, response, comet); } catch (x) { _debug('Exception during execution of success callback: {}', x); } }, onFailure: function(request, reason, exception) { try { _handleFailure.call(self, request, messages, reason, exception, comet); } catch (x) { _debug('Exception during execution of failure callback: {}', x); } } }; _debug('Sending request to {}, message(s): {}', envelope.url, JSON.stringify(envelope.messages)); _transport.send(envelope, comet); }; function _applyIncomingExtensions(message) { $.each(_extensions, function(index, extension) { var callback = extension.extension.incoming; if (callback && typeof callback === 'function') { _debug('Calling incoming extension \'{}\', callback \'{}\'', extension.name, callback.name); message = _applyExtension(extension.name, callback, message) || message; } }); return message; }; function _applyOutgoingExtensions(message) { $.each(_extensions, function(index, extension) { var callback = extension.extension.outgoing; if (callback && typeof callback === 'function') { _debug('Calling outgoing extension \'{}\', callback \'{}\'', extension.name, callback.name); message = _applyExtension(extension.name, callback, message) || message; } }); return message; }; function _applyExtension(name, callback, message) { try { return callback(message); } catch (x) { _debug('Exception during execution of extension \'{}\': {}', name, x); return message; } }; function _handleSuccess(request, response, comet) { var messages = _convertToMessages(response); _debug('Received response {}', JSON.stringify(messages)); var success = true; $.each(messages, function(index, message) { message = _applyIncomingExtensions(message); if (message.advice) _advice = message.advice; // Plain user messages do not have the successful property var successful = message.successful; success = success && (successful === undefined || successful); var channel = message.channel; switch (channel) { case '/meta/handshake': _handshakeSuccess(message); break; case '/meta/connect': _connectSuccess(message); break; case '/meta/disconnect': _disconnectSuccess(message); break; case '/meta/subscribe':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -