jquery.cometd.js
来自「jetty SERVER連接資料庫用的軟體」· JavaScript 代码 · 共 1,436 行 · 第 1/4 页
JS
1,436 行
* }
* 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?