You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by pa...@apache.org on 2012/05/04 14:12:22 UTC
[18/24] git commit: more work to get IE working
more work to get IE working
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/c3d90823
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/c3d90823
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/c3d90823
Branch: refs/heads/master
Commit: c3d908235ae6561092b84a1f2e6062944b14038b
Parents: 15d7b85
Author: Emond Papegaaij <pa...@apache.org>
Authored: Tue Apr 3 20:59:29 2012 +0200
Committer: Emond Papegaaij <pa...@apache.org>
Committed: Thu Apr 19 11:07:55 2012 +0200
----------------------------------------------------------------------
.../wicket/atmosphere/AtmosphereBehavior.java | 8 -
.../apache/wicket/atmosphere/jquery.atmosphere.js | 260 +++++++++++----
.../wicket/atmosphere/jquery.wicketatmosphere.js | 2 +-
wicket-examples/src/main/webapp/WEB-INF/web.xml | 4 +
4 files changed, 208 insertions(+), 66 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/c3d90823/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/AtmosphereBehavior.java
----------------------------------------------------------------------
diff --git a/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/AtmosphereBehavior.java b/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/AtmosphereBehavior.java
index 36f2074..f6d07f3 100644
--- a/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/AtmosphereBehavior.java
+++ b/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/AtmosphereBehavior.java
@@ -111,14 +111,6 @@ public class AtmosphereBehavior extends Behavior
if (transport.equalsIgnoreCase(HeaderConfig.LONG_POLLING_TRANSPORT))
{
Meteor meteor = Meteor.lookup(event.getResource().getRequest());
- meteor.removeListener(this);
- meteor.resume();
- }
- else if (transport.equalsIgnoreCase(HeaderConfig.STREAMING_TRANSPORT) &&
- (System.currentTimeMillis() - connectedAt) > 10000)
- {
- Meteor meteor = Meteor.lookup(event.getResource().getRequest());
- meteor.removeListener(this);
meteor.resume();
}
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/c3d90823/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js
----------------------------------------------------------------------
diff --git a/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js b/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js
index ea0fcec..20d292a 100644
--- a/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js
+++ b/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.atmosphere.js
@@ -12,6 +12,8 @@
* limitations under the License.
*/
/*
+ * Part of this code has been taked from
+ *
* jQuery Stream @VERSION
* Comet Streaming JavaScript Library
* http://code.google.com/p/jquery-stream/
@@ -40,6 +42,13 @@ jQuery.atmosphere = function() {
requests : [],
callbacks : [],
+ onError : function(response) {},
+ onClose : function(response) {},
+ onOpen : function(response) {},
+ onMessage : function(response) {},
+ onReconnect : function(request, response) {},
+ onMessagePublished : function(response) {},
+
AtmosphereRequest : function(options) {
/**
@@ -72,10 +81,19 @@ jQuery.atmosphere = function() {
webSocketPathDelimiter: "@@",
enableXDR : false,
rewriteURL : false,
- attachHeadersAsQueryString : false,
- executeCallbackBeforeReconnect : true,
+ attachHeadersAsQueryString : true,
+ executeCallbackBeforeReconnect : false,
readyState : 0,
- lastTimestamp : 0
+ lastTimestamp : 0,
+ withCredentials : false,
+ trackMessageLength : false ,
+ messageDelimiter : '|',
+ onError : function(response) {},
+ onClose : function(response) {},
+ onOpen : function(response) {},
+ onMessage : function(response) {},
+ onReconnect : function(request, response) {},
+ onMessagePublished : function(response) {}
};
/**
@@ -85,6 +103,7 @@ jQuery.atmosphere = function() {
var _response = {
status: 200,
responseBody : '',
+ expectedBodySize : -1,
headers : [],
state : "messageReceived",
transport : "polling",
@@ -94,14 +113,14 @@ jQuery.atmosphere = function() {
/**
* {number} Request id.
- *
+ *
* @private
*/
var _uuid = 0;
/**
* {websocket} Opened web socket.
- *
+ *
* @private
*/
var _websocket = null;
@@ -109,42 +128,42 @@ jQuery.atmosphere = function() {
/**
* {XMLHttpRequest, ActiveXObject} Opened ajax request (in case of
* http-streaming or long-polling)
- *
+ *
* @private
*/
var _activeRequest = null;
/**
* {Object} Object use for streaming with IE.
- *
+ *
* @private
*/
var _ieStream = null;
/**
* {Object} Object use for jsonp transport.
- *
+ *
* @private
*/
var _jqxhr = null;
/**
* {boolean} If request has been subscribed or not.
- *
+ *
* @private
*/
var _subscribed = true;
/**
* {number} Number of test reconnection.
- *
+ *
* @private
*/
var _requestCount = 0;
/**
* {boolean} If request is currently aborded.
- *
+ *
* @private
*/
var _abordingConnection = false;
@@ -154,7 +173,7 @@ jQuery.atmosphere = function() {
/**
* Initialize atmosphere request object.
- *
+ *
* @private
*/
function _init() {
@@ -180,7 +199,7 @@ jQuery.atmosphere = function() {
/**
* Subscribe request using request transport. <br>
* If request is currently opened, this one will be closed.
- *
+ *
* @param {Object}
* Request parameters.
* @private
@@ -197,7 +216,7 @@ jQuery.atmosphere = function() {
/**
* Check if web socket is supported (check for custom implementation
* provided by request object or browser implementation).
- *
+ *
* @returns {boolean} True if web socket is supported, false
* otherwise.
* @private
@@ -211,7 +230,7 @@ jQuery.atmosphere = function() {
* If request transport is 'websocket' but websocket can't be
* opened, request will automatically reconnect using fallback
* transport.
- *
+ *
* @private
*/
function _execute() {
@@ -247,7 +266,7 @@ jQuery.atmosphere = function() {
/**
* Execute request using jsonp transport.
- *
+ *
* @param request
* {Object} request Request parameters, if
* undefined _request object will be used.
@@ -282,17 +301,22 @@ jQuery.atmosphere = function() {
},
jsonp : "jsonpTransport",
success: function(json) {
- if (rq.executeCallbackBeforeReconnect) {
+ if (!rq.executeCallbackBeforeReconnect) {
_reconnect(_jqxhr, rq);
}
var msg = json.message;
if (msg != null && typeof msg != 'string') {
- msg = jQuery.stringifyJSON(msg);
+ try {
+ msg = jQuery.stringifyJSON(msg);
+ } catch (err) {
+ // The message was partial
+ }
}
+
_prepareCallback(msg, "messageReceived", 200, rq.transport);
- if (!rq.executeCallbackBeforeReconnect) {
+ if (rq.executeCallbackBeforeReconnect) {
_reconnect(_jqxhr, rq);
}
},
@@ -305,7 +329,7 @@ jQuery.atmosphere = function() {
/**
* Build websocket object.
- *
+ *
* @param location
* {string} Web socket url.
* @returns {websocket} Web socket object.
@@ -325,7 +349,7 @@ jQuery.atmosphere = function() {
/**
* Build web socket url from request url.
- *
+ *
* @return {string} Web socket url (start with "ws" or "wss" for
* secure web socket).
* @private
@@ -343,7 +367,7 @@ jQuery.atmosphere = function() {
* Open web socket. <br>
* Automatically use fallback transport if web socket can't be
* opened.
- *
+ *
* @private
*/
function _executeWebSocket() {
@@ -383,8 +407,14 @@ jQuery.atmosphere = function() {
_response.state = 'messageReceived';
_response.status = 200;
- _response.responseBody = message.data;
- _invokeCallback();
+
+ var message = message.data;
+ var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
+
+ if (!skipCallbackInvocation) {
+ _invokeCallback();
+ _response.responseBody = '';
+ }
};
_websocket.onerror = function(message) {
@@ -458,9 +488,44 @@ jQuery.atmosphere = function() {
}
/**
+ * Track received message and make sure callbacks/functions are only invoked when the complete message
+ * has been received.
+ *
+ * @param message
+ * @param request
+ * @param response
+ */
+ function _trackMessageSize(message, request, response) {
+ if (request.trackMessageLength) {
+ // The message length is the included within the message
+ var messageStart = message.indexOf(request.messageDelimiter);
+
+ var length = response.expectedBodySize;
+ if (messageStart != -1) {
+ length = message.substring(0, messageStart);
+ message = message.substring(messageStart + 1);
+ response.expectedBodySize = length;
+ }
+
+ if (messageStart != -1) {
+ response.responseBody = message;
+ } else {
+ response.responseBody += message;
+ }
+
+ if (response.responseBody.length != length) {
+ return true;
+ }
+ } else {
+ response.responseBody = message;
+ }
+ return false;
+ }
+
+ /**
* Reconnect request with fallback transport. <br>
* Used in case websocket can't be opened.
- *
+ *
* @private
*/
function _reconnectWithFallbackTransport() {
@@ -472,11 +537,11 @@ jQuery.atmosphere = function() {
/**
* Get url from request and attach headers to it.
- *
+ *
* @param request
* {Object} request Request parameters, if
* undefined _request object will be used.
- *
+ *
* @returns {Object} Request object, if undefined,
* _request object will be used.
* @private
@@ -497,9 +562,15 @@ jQuery.atmosphere = function() {
return url;
}
- url += "?X-Atmosphere-tracking-id=" + _uuid;
+ url += (url.indexOf('?') != -1) ? '&' : '?';
+ url += "X-Atmosphere-tracking-id=" + _uuid;
url += "&X-Atmosphere-Framework=" + jQuery.atmosphere.version;
url += "&X-Atmosphere-Transport=" + rq.transport;
+
+ if (rq.trackMessageLength) {
+ url += "&X-Atmosphere-TrackMessageSize=" + "true";
+ }
+
if (rq.lastTimestamp != undefined) {
url += "&X-Cache-Date=" + rq.lastTimestamp;
} else {
@@ -524,7 +595,7 @@ jQuery.atmosphere = function() {
* Build ajax request. <br>
* Ajax Request is an XMLHttpRequest object, except for IE6 where
* ajax request is an ActiveXObject.
- *
+ *
* @return {XMLHttpRequest, ActiveXObject} Ajax request.
* @private
*/
@@ -546,7 +617,7 @@ jQuery.atmosphere = function() {
/**
* Execute ajax request. <br>
- *
+ *
* @param request
* {Object} request Request parameters, if
* undefined _request object will be used.
@@ -573,7 +644,7 @@ jQuery.atmosphere = function() {
_ieXDR(rq);
return;
}
-
+
if (rq.requestCount++ < rq.maxRequest) {
var ajaxRequest = _buildAjaxRequest();
_doRequest(ajaxRequest, rq, true);
@@ -608,7 +679,7 @@ jQuery.atmosphere = function() {
return;
}
- var junkForWebkit = false;
+ var skipCallbackInvocation = false;
var update = false;
// Remote server disconnected us, reconnect.
@@ -652,25 +723,26 @@ jQuery.atmosphere = function() {
var responseText = ajaxRequest.responseText;
this.previousLastIndex = rq.lastIndex;
if (rq.transport == 'streaming') {
- _response.responseBody = responseText.substring(rq.lastIndex, responseText.length);
+ var text = responseText.substring(rq.lastIndex, responseText.length);
_response.isJunkEnded = true;
- if (rq.lastIndex == 0 && _response.responseBody.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1) {
+ if (rq.lastIndex == 0 && text.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1) {
_response.isJunkEnded = false;
}
if (!_response.isJunkEnded) {
var endOfJunk = "<!-- EOD -->";
var endOfJunkLenght = endOfJunk.length;
- var junkEnd = _response.responseBody.indexOf(endOfJunk) + endOfJunkLenght;
+ var junkEnd = text.indexOf(endOfJunk) + endOfJunkLenght;
- if (junkEnd > endOfJunkLenght && junkEnd != _response.responseBody.length) {
- _response.responseBody = _response.responseBody.substring(junkEnd);
+ if (junkEnd > endOfJunkLenght && junkEnd != text.length) {
+ _response.responseBody = text.substring(junkEnd);
} else {
- junkForWebkit = true;
+ skipCallbackInvocation = true;
}
} else {
- _response.responseBody = responseText.substring(rq.lastIndex, responseText.length);
+ var message = responseText.substring(rq.lastIndex, responseText.length);
+ skipCallbackInvocation = _trackMessageSize(message, rq, _response);
}
rq.lastIndex = responseText.length;
@@ -698,11 +770,11 @@ jQuery.atmosphere = function() {
}, 0);
}
- if (junkForWebkit) {
+ if (skipCallbackInvocation) {
return;
}
} else {
- _response.responseBody = responseText;
+ skipCallbackInvocation = _trackMessageSize(responseText, rq, _response);
rq.lastIndex = responseText.length;
}
@@ -719,7 +791,7 @@ jQuery.atmosphere = function() {
_response.state = "messagePublished";
}
- if (rq.executeCallbackBeforeReconnect) {
+ if (!rq.executeCallbackBeforeReconnect) {
_reconnect(ajaxRequest, rq, false);
}
@@ -729,7 +801,7 @@ jQuery.atmosphere = function() {
}
_invokeCallback();
- if (!rq.executeCallbackBeforeReconnect) {
+ if (rq.executeCallbackBeforeReconnect) {
_reconnect(ajaxRequest, rq, false);
}
@@ -771,6 +843,13 @@ jQuery.atmosphere = function() {
if (create) {
ajaxRequest.open(request.method, url, true);
}
+
+ if (request.withCredentials) {
+ if ("withCredentials" in ajaxRequest) {
+ ajaxRequest.withCredentials = true;
+ }
+ }
+
ajaxRequest.setRequestHeader("X-Atmosphere-Framework", jQuery.atmosphere.version);
ajaxRequest.setRequestHeader("X-Atmosphere-Transport", request.transport);
if (request.lastTimestamp != undefined) {
@@ -779,6 +858,10 @@ jQuery.atmosphere = function() {
ajaxRequest.setRequestHeader("X-Cache-Date", 0);
}
+ if (request.trackMessageLength) {
+ ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true")
+ }
+
if (request.contentType != '') {
ajaxRequest.setRequestHeader("Content-Type", request.contentType);
}
@@ -794,8 +877,6 @@ jQuery.atmosphere = function() {
function _reconnect(ajaxRequest, request, force) {
if (force || (request.suspend && ajaxRequest.status == 200 && request.transport != 'streaming' && _subscribed)) {
- _request.method = 'GET';
- _request.data = "";
_executeRequest();
}
}
@@ -926,7 +1007,6 @@ jQuery.atmosphere = function() {
open: function() {
var iframe = doc.createElement("iframe");
- rq.attachHeadersAsQueryString = true;
url = _attachHeaders(rq);
if (rq.data != '') {
url += "&X-Atmosphere-Post-Body=" + rq.data;
@@ -1037,7 +1117,7 @@ jQuery.atmosphere = function() {
/**
* Send message. <br>
* Will be automatically dispatch to other connected.
- *
+ *
* @param {Object,
* string} Message to send.
* @private
@@ -1057,7 +1137,7 @@ jQuery.atmosphere = function() {
/**
* Send a message using currently opened ajax request (using
* http-streaming or long-polling). <br>
- *
+ *
* @param {string, Object} Message to send. This is an object, string
* message is saved in data member.
* @private
@@ -1070,7 +1150,7 @@ jQuery.atmosphere = function() {
/**
* Send a message using currently opened ie streaming (using
* http-streaming or long-polling). <br>
- *
+ *
* @param {string, Object} Message to send. This is an object, string
* message is saved in data member.
* @private
@@ -1081,7 +1161,7 @@ jQuery.atmosphere = function() {
/**
* Send a message using jsonp transport. <br>
- *
+ *
* @param {string, Object} Message to send. This is an object, string
* message is saved in data member.
* @private
@@ -1137,7 +1217,7 @@ jQuery.atmosphere = function() {
/**
* Send a message using currently opened websocket. <br>
- *
+ *
* @param {string, Object}
* Message to send. This is an object, string message is
* saved in data member.
@@ -1170,17 +1250,56 @@ jQuery.atmosphere = function() {
}
function _prepareCallback(messageBody, state, errorCode, transport) {
+
+ var skipCallbackInvocation = false
+ if (state == "messageReceived") {
+ if (_trackMessageSize(messageBody, _request, _response)) return;
+ }
+
_response.transport = transport;
_response.status = errorCode;
- _response.responseBody = messageBody;
+
+ // If not -1, we have buffered the message.
+ if (_response.expectedBodySize == -1) {
+ _response.responseBody = messageBody;
+ }
_response.state = state;
_invokeCallback();
}
+ function _invokeFunction(response) {
+ _f(response, _request);
+ // Global
+ _f(response, jQuery.atmosphere);
+ }
+
+ function _f(response, f) {
+ switch (response.state) {
+ case "messageReceived" :
+ if (typeof(f.onMessage) != 'undefined') f.onMessage(response);
+ break;
+ case "error" :
+ if (typeof(f.onError) != 'undefined') f.onError(response);
+ break;
+ case "opening" :
+ if (typeof(f.onOpen) != 'undefined') f.onOpen(response);
+ break;
+ case "messagePublished" :
+ if (typeof(f.onMessagePublished) != 'undefined') f.onMessagePublished(response);
+ break;
+ case "re-opening" :
+ if (typeof(f.onReconnect) != 'undefined') f.onReconnect(_request, response);
+ break;
+ case "closed" :
+ if (typeof(f.onClose) != 'undefined') f.onClose(response);
+ break;
+ }
+ }
+
/**
* Invoke request callbacks.
- *
+ *
* @private
*/
function _invokeCallback() {
@@ -1188,10 +1307,16 @@ jQuery.atmosphere = function() {
func(_response);
};
+ _invokeFunction(_response);
+
// Invoke global callbacks
if (jQuery.atmosphere.callbacks.length > 0) {
jQuery.atmosphere.debug("Invoking " + jQuery.atmosphere.callbacks.length + " global callbacks: " + _response.state);
- jQuery.each(jQuery.atmosphere.callbacks, call);
+ try {
+ jQuery.each(jQuery.atmosphere.callbacks, call);
+ } catch (e) {
+ jQuery.atmosphere.log(_request.logLevel, ["Callback exception" + e]);
+ }
}
// Invoke request callback
@@ -1199,13 +1324,17 @@ jQuery.atmosphere = function() {
if (_request.logLevel == 'debug') {
jQuery.atmosphere.debug("Invoking request callbacks");
}
- _request.callback(_response);
+ try {
+ _request.callback(_response);
+ } catch (e) {
+ jQuery.atmosphere.log(_request.logLevel, ["Callback exception" + e]);
+ }
}
}
/**
* Close request.
- *
+ *
* @private
*/
function _close() {
@@ -1268,7 +1397,12 @@ jQuery.atmosphere = function() {
if (typeof(callback) == 'function') {
jQuery.atmosphere.addCallback(callback);
}
- request.url = url;
+
+ if (typeof(url) != "string") {
+ request = url;
+ } else {
+ request.url = url;
+ }
var rq = new jQuery.atmosphere.AtmosphereRequest(request);
jQuery.atmosphere.requests[jQuery.atmosphere.requests.length] = rq;
@@ -1317,12 +1451,24 @@ jQuery.atmosphere = function() {
}
},
+ publish: function(request) {
+ if (typeof(request.callback) == 'function') {
+ jQuery.atmosphere.addCallback(callback);
+ }
+ request.transport = "polling";
+
+ var rq = new jQuery.atmosphere.AtmosphereRequest(request);
+ jQuery.atmosphere.requests[jQuery.atmosphere.requests.length] = rq;
+ return rq;
+ },
+
checkCORSSupport : function() {
if (jQuery.browser.msie && !window.XDomainRequest) {
return true;
} else if (jQuery.browser.opera) {
return true;
}
+
// Force Android to use CORS as some version like 2.2.3 fail otherwise
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1;
http://git-wip-us.apache.org/repos/asf/wicket/blob/c3d90823/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.wicketatmosphere.js
----------------------------------------------------------------------
diff --git a/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.wicketatmosphere.js b/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.wicketatmosphere.js
index 80e6d7d..be51a2c 100644
--- a/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.wicketatmosphere.js
+++ b/wicket-atmosphere/src/main/java/org/apache/wicket/atmosphere/jquery.wicketatmosphere.js
@@ -32,7 +32,7 @@
var connectedEndpoint = $.atmosphere.subscribe(params.url,
!callbackAdded ? callback : null, $.atmosphere.request = {
- logLevel : "info",
+ logLevel : "debug",
transport : "websocket",
// transport : "streaming",
// transport : "long-polling",
http://git-wip-us.apache.org/repos/asf/wicket/blob/c3d90823/wicket-examples/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/webapp/WEB-INF/web.xml b/wicket-examples/src/main/webapp/WEB-INF/web.xml
index 7061765..2491827 100644
--- a/wicket-examples/src/main/webapp/WEB-INF/web.xml
+++ b/wicket-examples/src/main/webapp/WEB-INF/web.xml
@@ -803,6 +803,10 @@
<param-value>true</param-value>
</init-param>
<init-param>
+ <param-name>org.atmosphere.cpr.CometSupport.maxInactiveActivity</param-name>
+ <param-value>30000</param-value>
+ </init-param>
+ <init-param>
<param-name>filterMappingUrlPattern</param-name>
<param-value>/atmosphere/*</param-value>
</init-param>