From ac67fe763e2eae46db7cbba056bc9634c24a8e79 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 26 Jun 2013 22:35:13 +0800 Subject: [PATCH] IDEMPIERE-729 Firefox becomes very slow randomly after working on zkwebui. Reduce timeout and GC cycle for xmlhttprequest. --- .../zk/atmosphere/AtmosphereServerPush.java | 5 +- .../js/jawwa/atmosphere/jquery.atmosphere.js | 2505 ----------------- .../src/web/js/jawwa/atmosphere/serverpush.js | 59 +- .../src/web/js/jawwa/atmosphere/zk.wpd | 1 - 4 files changed, 30 insertions(+), 2540 deletions(-) delete mode 100644 org.adempiere.ui.zk/WEB-INF/src/web/js/jawwa/atmosphere/jquery.atmosphere.js diff --git a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java index bc852d43c6..6380825ee1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java +++ b/org.adempiere.ui.zk/WEB-INF/src/fi/jawsy/jawwa/zk/atmosphere/AtmosphereServerPush.java @@ -49,7 +49,7 @@ public class AtmosphereServerPush implements ServerPush { private static final String ON_ACTIVATE_DESKTOP = "onActivateDesktop"; - public static final int DEFAULT_TIMEOUT = 1000 * 60 * 5; + public static final int DEFAULT_TIMEOUT = 1000 * 60 * 2; private final AtomicReference desktop = new AtomicReference(); @@ -181,8 +181,7 @@ public class AtmosphereServerPush implements ServerPush { } log.debug("Starting server push for " + desktop); - int clientTimeout = timeout + 1000 * 60; - Clients.response("jawwa.atmosphere.serverpush", new AuScript(null, "jawwa.atmosphere.startServerPush('" + desktop.getId() + "', " + clientTimeout + Clients.response("jawwa.atmosphere.serverpush", new AuScript(null, "jawwa.atmosphere.startServerPush('" + desktop.getId() + "', " + timeout + ");")); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/web/js/jawwa/atmosphere/jquery.atmosphere.js b/org.adempiere.ui.zk/WEB-INF/src/web/js/jawwa/atmosphere/jquery.atmosphere.js deleted file mode 100644 index 286c728330..0000000000 --- a/org.adempiere.ui.zk/WEB-INF/src/web/js/jawwa/atmosphere/jquery.atmosphere.js +++ /dev/null @@ -1,2505 +0,0 @@ -/** - * Copyright 2012 Jeanfrancois Arcand - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * IE streaming/XDR supports is copied/highly inspired by http://code.google.com/p/jquery-stream/ - * - * Copyright 2011, Donghwan Kim - * Licensed under the Apache License, Version 2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * LocalStorage supports is copied/highly inspired by https://github.com/flowersinthesand/jquery-socket - * Copyright 2011, Donghwan Kim - * Licensed under the Apache License, Version 2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * */ -/** - * Official documentation of this library: https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-API - */ -jQuery.atmosphere = function() { - jQuery(window).bind("unload.atmosphere", function() { - jQuery.atmosphere.unsubscribe(); - }); - - // Prevent ESC to kill the connection from Firefox. - jQuery(window).keypress(function(e){ - if(e.keyCode == 27){ - e.preventDefault(); - } - }); - - var parseHeaders = function(headerString) { - var match, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, headers = {}; - while (match = rheaders.exec(headerString)) { - headers[match[1]] = match[2]; - } - return headers; - }; - - return { - version : "1.0.3", - requests : [], - callbacks : [], - - onError : function(response) { - }, - onClose : function(response) { - }, - onOpen : function(response) { - }, - onMessage : function(response) { - }, - onReconnect : function(request, response) { - }, - onMessagePublished : function(response) { - }, - onTransportFailure : function(response) { - }, - onLocalMessage : function (response) { - }, - - AtmosphereRequest : function(options) { - - /** - * {Object} Request parameters. - * @private - */ - var _request = { - timeout: 300000, - method: 'GET', - headers: {}, - contentType : '', - callback: null, - url : '', - data : '', - suspend : true, - maxRequest : 60, - reconnect : true, - maxStreamingLength : 10000000, - lastIndex : 0, - logLevel : 'info', - requestCount : 0, - fallbackMethod: 'GET', - fallbackTransport : 'streaming', - transport : 'long-polling', - webSocketImpl: null, - webSocketUrl: null, - webSocketPathDelimiter: "@@", - enableXDR : false, - rewriteURL : false, - attachHeadersAsQueryString : true, - executeCallbackBeforeReconnect : false, - readyState : 0, - lastTimestamp : 0, - withCredentials : false, - trackMessageLength : false , - messageDelimiter : '|', - connectTimeout : -1, - reconnectInterval : 0, - dropAtmosphereHeaders : true, - uuid : 0, - shared : false, - readResponsesHeaders : true, - onError : function(response) { - }, - onClose : function(response) { - }, - onOpen : function(response) { - }, - onMessage : function(response) { - }, - onReconnect : function(request, response) { - }, - onMessagePublished : function(response) { - }, - onTransportFailure : function (reason, request) { - }, - onLocalMessage : function (request) { - } - }; - - /** - * {Object} Request's last response. - * @private - */ - var _response = { - status: 200, - responseBody : '', - headers : [], - state : "messageReceived", - transport : "polling", - error: null, - request : null, - partialMessage : "", - id : 0 - }; - - /** - * {websocket} Opened web socket. - * - * @private - */ - var _websocket = null; - - /** - * {SSE} Opened SSE. - * - * @private - */ - var _sse = null; - - /** - * {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; - - /** - * A local "channel' of communication. - * @private - */ - var _localSocketF = null; - - /** - * The storage used. - * @private - */ - var _storageService; - - /** - * Local communication - * @private - */ - var _localStorageService = null; - - /** - * A Unique ID - * @private - */ - var guid = jQuery.now(); - - /** Trace time */ - var _traceTimer; - - // Automatic call to subscribe - _subscribe(options); - - /** - * Initialize atmosphere request object. - * - * @private - */ - function _init() { - _subscribed = true; - _abordingConnection = false; - _requestCount = 0; - - _websocket = null; - _sse = null; - _activeRequest = null; - _ieStream = null; - } - - /** - * Re-initialize atmosphere object. - * @private - */ - function _reinit() { - _clearState(); - _init(); - } - - /** - * Subscribe request using request transport.
- * If request is currently opened, this one will be closed. - * - * @param {Object} - * Request parameters. - * @private - */ - function _subscribe(options) { - _reinit(); - - _request = jQuery.extend(_request, options); - } - - /** - * 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 - */ - function _supportWebsocket() { - return _request.webSocketImpl != null || window.WebSocket || window.MozWebSocket; - } - - /** - * Check if server side events (SSE) is supported (check for custom implementation - * provided by request object or browser implementation). - * - * @returns {boolean} True if web socket is supported, false - * otherwise. - * @private - */ - function _supportSSE() { - return window.EventSource; - } - - /** - * Open request using request transport.
- * If request transport is 'websocket' but websocket can't be - * opened, request will automatically reconnect using fallback - * transport. - * - * @private - */ - function _execute() { - // Shared across multiple tabs/windows. - if (_request.shared) { - - var version = 0; - if (navigator.appVersion.indexOf("MSIE") != -1) { - version = parseFloat(navigator.appVersion.split("MSIE")[1]); - } - - // Multi Tab aren't working on IE 8. Tested with atmosphere.js and jquery-socket.js - // both pops up a blank page. - if (version != 8) { - _localStorageService = _local(_request); - if (_localStorageService != null) { - if (_request.logLevel == 'debug') { - jQuery.atmosphere.debug("Storage service available. All communication will be local"); - } - - if (_localStorageService.open(_request)) { - // Local connection. - return; - } - } - - if (_request.logLevel == 'debug') { - jQuery.atmosphere.debug("No Storage service available."); - } - } else { - jQuery.atmosphere.info("Multi tab not supported on IE 8."); - } - // Wasn't local or an error occurred - _localStorageService = null; - } - - if (_request.transport != 'websocket' && _request.transport != 'sse') { - _open('opening', _request.transport, _request); - _executeRequest(); - - } else if (_request.transport == 'websocket') { - if (!_supportWebsocket()) { - _reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport + ")"); - } else { - _executeWebSocket(false); - } - } else if (_request.transport == 'sse') { - if (!_supportSSE()) { - _reconnectWithFallbackTransport("Server Side Events(SSE) is not supported, using request.fallbackTransport (" + _request.fallbackTransport + ")"); - } else { - _executeSSE(false); - } - } - } - - function _local(request) { - var trace, connector, orphan, name = "atmosphere-" + request.url, connectors = { - storage: function() { - if (!jQuery.atmosphere.supportStorage()) { - return; - } - - var storage = window.localStorage, - get = function(key) { - return jQuery.parseJSON(storage.getItem(name + "-" + key)); - }, - set = function(key, value) { - storage.setItem(name + "-" + key, jQuery.stringifyJSON(value)); - }; - - return { - init: function() { - set("children", get("children").concat([guid])); - jQuery(window).on("storage.socket", function(event) { - event = event.originalEvent; - if (event.key === name && event.newValue) { - listener(event.newValue); - } - }); - return get("opened"); - }, - signal: function(type, data) { - storage.setItem(name, jQuery.stringifyJSON({target: "p", type: type, data: data})); - }, - close: function() { - var index, children = get("children"); - - jQuery(window).off("storage.socket"); - if (children) { - index = jQuery.inArray(request.id, children); - if (index > -1) { - children.splice(index, 1); - set("children", children); - } - } - } - }; - }, - windowref: function() { - var win = window.open("", name.replace(/\W/g, "")); - - if (!win || win.closed || !win.callbacks) { - return; - } - - return { - init: function() { - win.callbacks.push(listener); - win.children.push(guid); - return win.opened; - }, - signal: function(type, data) { - if (!win.closed && win.fire) { - win.fire(jQuery.stringifyJSON({target: "p", type: type, data: data})); - } - }, - close : function() { - function remove(array, e) { - var index = jQuery.inArray(e, array); - if (index > -1) { - array.splice(index, 1); - } - } - - // Removes traces only if the parent is alive - if (!orphan) { - remove(win.callbacks, listener); - remove(win.children, guid); - } - } - - }; - } - }; - - // Receives open, close and message command from the parent - function listener(string) { - var command = jQuery.parseJSON(string), data = command.data; - - if (command.target === "c") { - switch (command.type) { - case "open": - _open("opening", 'local', _request) - break; - case "close": - if (!orphan) { - orphan = true; - if (data.reason === "aborted") { - _close(); - } else { - // Gives the heir some time to reconnect - if (data.heir === guid) { - _execute(); - } else { - setTimeout(function() { - _execute(); - }, 100); - } - } - } - break; - case "message": - _prepareCallback(data, "messageReceived", 200, request.transport); - break; - case "localMessage": - _localMessage(data); - break; - } - } - } - - function findTrace() { - var matcher = new RegExp("(?:^|; )(" + encodeURIComponent(name) + ")=([^;]*)").exec(document.cookie); - if (matcher) { - return jQuery.parseJSON(decodeURIComponent(matcher[2])); - } - } - - // Finds and validates the parent socket's trace from the cookie - trace = findTrace(); - if (!trace || jQuery.now() - trace.ts > 1000) { - return; - } - - // Chooses a connector - connector = connectors.storage() || connectors.windowref(); - if (!connector) { - return; - } - - return { - open: function() { - var parentOpened; - - // Checks the shared one is alive - _traceTimer = setInterval(function() { - var oldTrace = trace; - trace = findTrace(); - if (!trace || oldTrace.ts === trace.ts) { - // Simulates a close signal - listener(jQuery.stringifyJSON({target: "c", type: "close", data: {reason: "error", heir: oldTrace.heir}})); - } - }, 1000); - - parentOpened = connector.init(); - if (parentOpened) { - // Firing the open event without delay robs the user of the opportunity to bind connecting event handlers - setTimeout(function() { - _open("opening", 'local', request) - }, 50); - } - return parentOpened; - }, - send: function(event) { - connector.signal("send", event); - }, - localSend: function(event) { - connector.signal("localSend", jQuery.stringifyJSON({id: guid , event: event})); - }, - close: function() { - // Do not signal the parent if this method is executed by the unload event handler - if (!_abordingConnection) { - clearInterval(_traceTimer); - connector.signal("close"); - connector.close(); - } - } - }; - }; - - function share() { - var storageService, name = "atmosphere-" + _request.url, servers = { - // Powered by the storage event and the localStorage - // http://www.w3.org/TR/webstorage/#event-storage - storage: function() { - if (!jQuery.atmosphere.supportStorage()) { - return; - } - - var storage = window.localStorage; - - return { - init: function() { - // Handles the storage event - jQuery(window).on("storage.socket", function(event) { - event = event.originalEvent; - // When a deletion, newValue initialized to null - if (event.key === name && event.newValue) { - listener(event.newValue); - } - }); - }, - signal: function(type, data) { - storage.setItem(name, jQuery.stringifyJSON({target: "c", type: type, data: data})); - }, - get: function(key) { - return jQuery.parseJSON(storage.getItem(name + "-" + key)); - }, - set: function(key, value) { - storage.setItem(name + "-" + key, jQuery.stringifyJSON(value)); - }, - close : function() { - jQuery(window).off("storage.socket"); - storage.removeItem(name); - storage.removeItem(name + "-opened"); - storage.removeItem(name + "-children"); - } - - }; - }, - // Powered by the window.open method - // https://developer.mozilla.org/en/DOM/window.open - windowref: function() { - // Internet Explorer raises an invalid argument error - // when calling the window.open method with the name containing non-word characters - var neim = name.replace(/\W/g, ""), win = (jQuery('iframe[name="' + neim + '"]')[0] - || jQuery('