diff options
author | Johannes Dahlström <johannesd@vaadin.com> | 2013-05-21 10:18:22 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2013-05-21 11:45:16 +0000 |
commit | f8fb8b7bfdbf4d8c22ca512e937fe812803369c6 (patch) | |
tree | a90c4892f254d054db3a6642a94c3af3aa8d06e9 /WebContent/VAADIN | |
parent | 778de066b1f8b1608b40bdd98b61b6fee078442d (diff) | |
download | vaadin-framework-f8fb8b7bfdbf4d8c22ca512e937fe812803369c6.tar.gz vaadin-framework-f8fb8b7bfdbf4d8c22ca512e937fe812803369c6.zip |
Upgrade to Atmosphere 1.0.13 (#11861)
Change-Id: Ie9281ff5e9805be89942bf3ca8259740f49e15ab
Diffstat (limited to 'WebContent/VAADIN')
-rw-r--r-- | WebContent/VAADIN/jquery.atmosphere.js | 553 |
1 files changed, 281 insertions, 272 deletions
diff --git a/WebContent/VAADIN/jquery.atmosphere.js b/WebContent/VAADIN/jquery.atmosphere.js index e9def6ae95..2b176668c1 100644 --- a/WebContent/VAADIN/jquery.atmosphere.js +++ b/WebContent/VAADIN/jquery.atmosphere.js @@ -49,7 +49,7 @@ jQuery.atmosphere = function() { }; return { - version : "1.0.12", + version : "1.0.13", requests : [], callbacks : [], @@ -138,13 +138,16 @@ jQuery.atmosphere = function() { */ var _response = { status: 200, + reasonPhrase : "OK", responseBody : '', + messages : [], headers : [], state : "messageReceived", transport : "polling", error: null, request : null, partialMessage : "", + errorHandled: false, id : 0 }; @@ -682,19 +685,21 @@ jQuery.atmosphere = function() { _close(); }; - _response.request = request; - var prevState = _response.state; - _response.state = state; - _response.status = 200; - var prevTransport = _response.transport; - _response.transport = transport; + if (_response.error == null) { + _response.request = request; + var prevState = _response.state; + _response.state = state; + _response.status = 200; + var prevTransport = _response.transport; + _response.transport = transport; - var _body = _response.responseBody; - _invokeCallback(); - _response.responseBody = _body; + var _body = _response.responseBody; + _invokeCallback(); + _response.responseBody = _body; - _response.state = prevState; - _response.transport = prevTransport; + _response.state = prevState; + _response.transport = prevTransport; + } } /** @@ -729,41 +734,43 @@ jQuery.atmosphere = function() { type : rq.method, dataType: "jsonp", error : function(jqXHR, textStatus, errorThrown) { - if (jqXHR.status < 300) { + _response.error = true; + if (jqXHR.status < 300 && rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) { _reconnect(_jqxhr, rq); } else { - _prepareCallback(textStatus, "error", jqXHR.status, rq.transport); + _onError(jqXHR.status, errorThrown); } }, jsonp : "jsonpTransport", success: function(json) { + if (rq.reconnect) { + if (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest) { + _readHeaders(_jqxhr, rq); - if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) { - _readHeaders(_jqxhr, rq); - - if (!rq.executeCallbackBeforeReconnect) { - _reconnect(_jqxhr, rq); - } + if (!rq.executeCallbackBeforeReconnect) { + _reconnect(_jqxhr, rq); + } - var msg = json.message; - if (msg != null && typeof msg != 'string') { - try { - msg = jQuery.stringifyJSON(msg); - } catch (err) { - // The message was partial + var msg = json.message; + if (msg != null && typeof msg != 'string') { + try { + msg = jQuery.stringifyJSON(msg); + } catch (err) { + // The message was partial + } } - } - if (_handleProtocol(rq, msg)) { - _prepareCallback(msg, "messageReceived", 200, rq.transport); - } + if (_handleProtocol(rq, msg)) { + _prepareCallback(msg, "messageReceived", 200, rq.transport); + } - if (rq.executeCallbackBeforeReconnect) { - _reconnect(_jqxhr, rq); + if (rq.executeCallbackBeforeReconnect) { + _reconnect(_jqxhr, rq); + } + } else { + jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]); + _onError(0, "maxRequest reached"); } - } else { - jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]); - _onError(); } }, data : rq.data, @@ -802,29 +809,32 @@ jQuery.atmosphere = function() { url : url, type : rq.method, error : function(jqXHR, textStatus, errorThrown) { + _response.error = true; if (jqXHR.status < 300) { _reconnect(_jqxhr, rq); } else { - _prepareCallback(textStatus, "error", jqXHR.status, rq.transport); + _onError(jqXHR.status, errorThrown); } }, success: function(data, textStatus, jqXHR) { - if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) { - if (!rq.executeCallbackBeforeReconnect) { - _reconnect(_jqxhr, rq); - } + if (rq.reconnect) { + if (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest) { + if (!rq.executeCallbackBeforeReconnect) { + _reconnect(_jqxhr, rq); + } - if (_handleProtocol(rq, data)) { - _prepareCallback(data, "messageReceived", 200, rq.transport); - } + if (_handleProtocol(rq, data)) { + _prepareCallback(data, "messageReceived", 200, rq.transport); + } - if (rq.executeCallbackBeforeReconnect) { - _reconnect(_jqxhr, rq); + if (rq.executeCallbackBeforeReconnect) { + _reconnect(_jqxhr, rq); + } + } else { + jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]); + _onError(0, "maxRequest reached"); } - } else { - jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]); - _onError(); } }, beforeSend : function(jqXHR) { @@ -912,7 +922,14 @@ jQuery.atmosphere = function() { } return; } - _sse = new EventSource(location, {withCredentials: _request.withCredentials}); + + try { + _sse = new EventSource(location, {withCredentials: _request.withCredentials}); + } catch (e) { + _onError(0, e); + _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending"); + return; + } if (_request.connectTimeout > 0) { _request.id = setTimeout(function() { @@ -944,31 +961,25 @@ jQuery.atmosphere = function() { return; } - if (!_handleProtocol(_request, message.data)) return; + var data = message.data; + + if (!_handleProtocol(_request, data)) return; _response.state = 'messageReceived'; _response.status = 200; - var message = message.data; - var skipCallbackInvocation = _trackMessageSize(message, _request, _response); - - if (jQuery.trim(message).length == 0) { - skipCallbackInvocation = true; - } - + var skipCallbackInvocation = _trackMessageSize(data, _request, _response); if (!skipCallbackInvocation) { _invokeCallback(); _response.responseBody = ''; + _response.messages = []; } }; _sse.onerror = function(message) { clearTimeout(_request.id); - _response.state = 'closed'; - _response.responseBody = ""; - _response.status = !sseOpened ? 501 : 200; - _invokeCallback(); + _invokeClose(sseOpened); _clearState(); if (_abordingConnection) { @@ -981,9 +992,10 @@ jQuery.atmosphere = function() { _executeSSE(true); }, _request.reconnectInterval); _response.responseBody = ""; + _response.messages = []; } else { jQuery.atmosphere.log(_request.logLevel, ["SSE reconnect maximum try reached " + _requestCount]); - _onError(); + _onError(0, "maxReconnectOnClose reached"); } } }; @@ -1025,7 +1037,6 @@ jQuery.atmosphere = function() { } _websocket = _getWebSocket(location); - if (_request.connectTimeout > 0) { _request.id = setTimeout(function() { if (!webSocketOpened) { @@ -1062,6 +1073,7 @@ jQuery.atmosphere = function() { } webSocketOpened = true; + _websocket.webSocketOpened = webSocketOpened; if (_request.method == 'POST') { _response.state = "messageReceived"; @@ -1078,17 +1090,18 @@ jQuery.atmosphere = function() { }, _request.reconnectInterval) }, _request.timeout); - if (!_handleProtocol(_request, message.data)) return; + var data = message.data; + + if (!_handleProtocol(_request, data)) return; _response.state = 'messageReceived'; _response.status = 200; - var message = message.data; - var skipCallbackInvocation = _trackMessageSize(message, _request, _response); - + var skipCallbackInvocation = _trackMessageSize(data, _request, _response); if (!skipCallbackInvocation) { _invokeCallback(); _response.responseBody = ''; + _response.messages = []; } }; @@ -1098,6 +1111,7 @@ jQuery.atmosphere = function() { _websocket.onclose = function(message) { if (closed) return + clearTimeout(_request.id); var reason = message.reason; if (reason === "") { @@ -1133,12 +1147,7 @@ jQuery.atmosphere = function() { jQuery.atmosphere.warn("Websocket closed, reason: " + reason); jQuery.atmosphere.warn("Websocket closed, wasClean: " + message.wasClean); - _response.state = 'closed'; - _response.responseBody = ""; - _response.status = !webSocketOpened ? 501 : 200; - _invokeCallback(); - clearTimeout(_request.id); - + _invokeClose(webSocketOpened); closed = true; if (_abordingConnection) { @@ -1151,12 +1160,13 @@ jQuery.atmosphere = function() { if (_request.reconnect && _requestCount++ < _request.maxReconnectOnClose) { _request.id = setTimeout(function() { _response.responseBody = ""; + _response.messages = []; _executeWebSocket(true); }, _request.reconnectInterval); } else { jQuery.atmosphere.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _requestCount]); jQuery.atmosphere.warn("Websocket error, reason: " + message.reason); - _onError(); + _onError(0, "maxReconnectOnClose reached"); } } }; @@ -1164,22 +1174,25 @@ jQuery.atmosphere = function() { function _handleProtocol(request, message) { // The first messages is always the uuid. - if (request.enableProtocol && request.firstMessage) { + if (jQuery.trim(message) != 0 && request.enableProtocol && request.firstMessage) { request.firstMessage = false; var messages = message.split(request.messageDelimiter); - request.uuid = messages[0]; - request.stime = messages[1]; + var pos = messages.length == 2 ? 0 : 1; + request.uuid = jQuery.trim(messages[pos]); + request.stime = jQuery.trim(messages[pos + 1]); return false; } return true; } - function _onError() { + function _onError(code, reason) { _clearState(); _response.state = 'error'; + _response.reasonPhrase = reason; _response.responseBody = ""; - _response.status = 500; + _response.messages = []; + _response.status = code; _invokeCallback(); } @@ -1203,7 +1216,7 @@ jQuery.atmosphere = function() { var messageLength = 0; var messageStart = message.indexOf(request.messageDelimiter); while (messageStart != -1) { - messageLength = message.substring(messageLength, messageStart); + messageLength = jQuery.trim(message.substring(messageLength, messageStart)); message = message.substring(messageStart + request.messageDelimiter.length, message.length); if (message.length == 0 || message.length < messageLength) break; @@ -1220,8 +1233,11 @@ jQuery.atmosphere = function() { if (messages.length != 0) { response.responseBody = messages.join(request.messageDelimiter); + response.messages = messages; return false; } else { + response.responseBody = ""; + response.messages = []; return true; } } else { @@ -1246,15 +1262,16 @@ jQuery.atmosphere = function() { } _request.transport = _request.fallbackTransport; - var reconnect = _request.reconnect && _requestCount++ < _request.maxReconnectOnClose; - if (reconnect && _request.transport != 'none' || _request.transport == null) { + var reconnectInterval = _request.connectTimeout == -1 ? 0 : _request.connectTimeout; + if (_request.reconnect && _request.transport != 'none' || _request.transport == null) { _request.method = _request.fallbackMethod; _response.transport = _request.fallbackTransport; + _request.fallbackTransport = 'none'; _request.id = setTimeout(function() { _execute(); - }, _request.reconnectInterval); - } else if (!reconnect) { - _onError(); + }, reconnectInterval); + } else { + _onError(500, "Unable to reconnect with fallback transport"); } } @@ -1357,6 +1374,9 @@ jQuery.atmosphere = function() { rq = request; } + rq.lastIndex = 0; + rq.readyState = 0; + // CORS fake using JSONP if ((rq.transport == 'jsonp') || ((rq.enableXDR) && (jQuery.atmosphere.checkCORSSupport()))) { _jsonp(rq); @@ -1380,6 +1400,14 @@ jQuery.atmosphere = function() { } } + var reconnectF = function() { + if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) { + _reconnect(ajaxRequest, rq, true); + } else { + _onError(0, "maxReconnectOnClose reached"); + } + }; + if (rq.reconnect && ( rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) { var ajaxRequest = _buildAjaxRequest(); _doRequest(ajaxRequest, rq, true); @@ -1392,162 +1420,129 @@ jQuery.atmosphere = function() { _response.transport = rq.transport; } - if (!jQuery.browser.msie) { - ajaxRequest.onerror = function() { - try { - _response.status = XMLHttpRequest.status; - } catch(e) { - _response.status = 500; - } + ajaxRequest.onabort = function () { + _invokeClose(true); + }; - if (!_response.status) { - _response.status = 500; - } - _clearState(); + ajaxRequest.onerror = function() { + _response.error = true; + try { + _response.status = XMLHttpRequest.status; + } catch(e) { + _response.status = 500; + } - if (rq.reconnect) { - _reconnect(ajaxRequest, rq, true); - } else { - _onError(); - } - }; - } + if (!_response.status) { + _response.status = 500; + } + _clearState(); + if (!_response.errorHandled) { + reconnectF(); + } + }; ajaxRequest.onreadystatechange = function() { if (_abordingConnection) { return; } - + _response.error = null; var skipCallbackInvocation = false; var update = false; - // Remote server disconnected us, reconnect. - if (rq.transport == 'streaming' + + // Opera doesn't call onerror if the server disconnect. + if (jQuery.browser.opera + && rq.transport == 'streaming' && rq.readyState > 2 && ajaxRequest.readyState == 4) { rq.readyState = 0; rq.lastIndex = 0; - _reconnect(ajaxRequest, rq, true); + reconnectF(); return; } rq.readyState = ajaxRequest.readyState; - if (ajaxRequest.readyState == 4) { - if (jQuery.browser.msie) { - update = true; - } else if (rq.transport == 'streaming') { - update = true; - } else if (rq.transport == 'long-polling') { - update = true; - clearTimeout(rq.id); - } - } else if (rq.transport == 'streaming' && jQuery.browser.msie && ajaxRequest.readyState >= 3) { + if (rq.transport == 'streaming' && ajaxRequest.readyState >= 3) { update = true; - } else if (!jQuery.browser.msie && ajaxRequest.readyState == 3 && ajaxRequest.status == 200 && rq.transport != 'long-polling') { + } else if (rq.transport == 'long-polling' && ajaxRequest.readyState === 4) { update = true; - } else { - clearTimeout(rq.id); } + clearTimeout(rq.id); if (update) { + // MSIE 9 and lower status can be higher than 1000, Chrome can be 0 + var status = 0; + if (ajaxRequest.readyState != 0) { + status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status; + } + + if (status >= 300 || status == 0) { + // Prevent onerror callback to be called + _response.errorHandled = true; + _clearState(); + reconnectF(); + return; + } var responseText = ajaxRequest.responseText; - // MSIE status can be higher than 1000, Chrome can be 0 - if (ajaxRequest.status >= 500 || ajaxRequest.status == 0) { - if (rq.reconnect) { - _reconnect(ajaxRequest, rq, true); - } else { - _onError(); + if (jQuery.trim(responseText.length) == 0 && rq.transport == 'long-polling') { + // For browser that aren't support onabort + if (!ajaxRequest.hasData) { + reconnectF(); + } else { + ajaxRequest.hasData = false; } return; } + ajaxRequest.hasData = true; _readHeaders(ajaxRequest, _request); if (rq.transport == 'streaming') { - var text = responseText.substring(rq.lastIndex, responseText.length); - _response.isJunkEnded = true; - - //fix junk is comming in parts - if (!_response.junkFull && (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1 || text.indexOf("<!-- EOD -->") == -1)) { - return; - } - _response.junkFull = true; - - //if it's the start and we see the junk start - //fix for reconnecting on chrome - junk is comming in parts - if (rq.lastIndex == 0 && text.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1 && text.indexOf("<!-- EOD -->") != -1) { - _response.isJunkEnded = false; - } - - if (!_response.isJunkEnded) { - var endOfJunk = "<!-- EOD -->"; - var endOfJunkLength = endOfJunk.length; - var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength; - - if (junkEnd > endOfJunkLength && junkEnd != text.length) { - _response.responseBody = text.substring(junkEnd); - rq.lastIndex = responseText.length; - if (!_handleProtocol( _request, _response.responseBody)) { - return; - } - skipCallbackInvocation = _trackMessageSize(_response.responseBody, rq, _response); - } else { - skipCallbackInvocation = true; - } - } else { + if (!jQuery.browser.opera) { var message = responseText.substring(rq.lastIndex, responseText.length); rq.lastIndex = responseText.length; - if (!_handleProtocol( _request, message)) { + if (!_handleProtocol(_request, message)) { return; } skipCallbackInvocation = _trackMessageSize(message, rq, _response); - } - rq.lastIndex = responseText.length; - - if (jQuery.browser.opera) { - jQuery.atmosphere.iterate(function() { - if (ajaxRequest.responseText.length > rq.lastIndex) { + } else { + jQuery.atmosphere.iterate(function () { + if (_response.status != 500 && ajaxRequest.responseText.length > rq.lastIndex) { try { _response.status = ajaxRequest.status; - _response.headers = parseHeaders(ajaxRequest.getAllResponseHeaders()); - - _readHeaders(ajaxRequest, _request); } - catch(e) { + catch (e) { _response.status = 404; } _response.state = "messageReceived"; - _response.responseBody = ajaxRequest.responseText.substring(rq.lastIndex); + + var message = ajaxRequest.responseText.substring(rq.lastIndex); rq.lastIndex = ajaxRequest.responseText.length; + if (_handleProtocol(_request, message)) { + skipCallbackInvocation = _trackMessageSize(message, rq, _response); + if (!skipCallbackInvocation) { + _invokeCallback(); + } - if (!_handleProtocol( _request, _response.responseBody)) { - _reconnect(ajaxRequest, rq, false); - return; - } - _invokeCallback(); - if ((rq.transport == 'streaming') && (ajaxRequest.responseText.length > rq.maxStreamingLength)) { - // Close and reopen connection on large data received - _clearState(); - _doRequest(_buildAjaxRequest(), rq, true); + _verifyStreamingLength(ajaxRequest, rq); } + } else if (_response.status > 400){ + rq.lastIndex = ajaxRequest.responseText.length; + return false; } }, 0); } - - if (skipCallbackInvocation) { - return; - } } else { if (!_handleProtocol( _request, responseText)) { _reconnect(ajaxRequest, rq, false); return; } - _trackMessageSize(responseText, rq, _response); + skipCallbackInvocation = _trackMessageSize(responseText, rq, _response); rq.lastIndex = responseText.length; } @@ -1575,17 +1570,15 @@ jQuery.atmosphere = function() { jQuery.atmosphere.log(rq.logLevel, ["parent.callback no longer supported with 0.8 version and up. Please upgrade"]); } - _invokeCallback(); + if (!skipCallbackInvocation) { + _invokeCallback(); + } if (rq.executeCallbackBeforeReconnect) { _reconnect(ajaxRequest, rq, false); } - if ((rq.transport == 'streaming') && (responseText.length > rq.maxStreamingLength)) { - // Close and reopen connection on large data received - _clearState(); - _doRequest(_buildAjaxRequest(), rq, true); - } + _verifyStreamingLength(ajaxRequest, rq); } }; ajaxRequest.send(rq.data); @@ -1606,7 +1599,7 @@ jQuery.atmosphere = function() { if (rq.logLevel == 'debug') { jQuery.atmosphere.log(rq.logLevel, ["Max re-connection reached."]); } - _onError(); + _onError(0, "maxRequest reached"); } } @@ -1651,13 +1644,13 @@ jQuery.atmosphere = function() { if (request.trackMessageLength) { ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true") } - - if (request.contentType != '') { - ajaxRequest.setRequestHeader("Content-Type", request.contentType); - } ajaxRequest.setRequestHeader("X-Atmosphere-tracking-id", request.uuid); } + if (request.contentType != '') { + ajaxRequest.setRequestHeader("Content-Type", request.contentType); + } + jQuery.each(request.headers, function(name, value) { var h = jQuery.isFunction(value) ? value.call(this, ajaxRequest, request, create, _response) : value; if (h != null) { @@ -1667,17 +1660,26 @@ jQuery.atmosphere = function() { } function _reconnect(ajaxRequest, request, force) { - var reconnect = request.reconnect && _requestCount++ < request.maxReconnectOnClose; + if (force || request.transport != 'streaming') { + if ( request.reconnect || (request.suspend && _subscribed)) { + var status = 0; + if (ajaxRequest.readyState != 0) { + status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status; + } + _response.status = status == 0 ? 204 : status; + _response.reason = status == 0 ? "Server resumed the connection or down." : "OK"; - if (reconnect && force || (request.suspend && ajaxRequest.status == 200 && request.transport != 'streaming' && _subscribed)) { - if (request.reconnect) { - _open('re-opening', request.transport, request); - request.id = setTimeout(function() { - _executeRequest(); - }, request.reconnectInterval); + var reconnectInterval = (request.connectTimeout == -1) ? 0 : request.connectTimeout; + + // Reconnect immedialtely + if (!force) { + request.id = setTimeout(function () { + _executeRequest(request); + }, reconnectInterval); + } else { + _executeRequest(request); + } } - } else if (!reconnect) { - _onError(); } } @@ -1702,21 +1704,6 @@ jQuery.atmosphere = function() { var lastIndex = 0; var xdrCallback = function (xdr) { var responseBody = xdr.responseText; - var isJunkEnded = false; - - if (responseBody.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1) { - isJunkEnded = true; - } - - if (isJunkEnded) { - var endOfJunk = "<!-- EOD -->"; - var endOfJunkLenght = endOfJunk.length; - var junkEnd = responseBody.indexOf(endOfJunk); - if (junkEnd !== -1) { - responseBody = responseBody.substring(junkEnd + endOfJunkLenght + lastIndex); - lastIndex += responseBody.length; - } - } if (!_handleProtocol(request, responseBody)) return; @@ -1747,10 +1734,8 @@ jQuery.atmosphere = function() { xdr.onerror = function() { // If the server doesn't send anything back to XDR will fail with polling if (rq.transport != 'polling') { - _prepareCallback(xdr.responseText, "error", 500, transport); + _reconnect(xdr, rq, false); } - - _reconnect(xdr, rq, false); }; // Handles close event @@ -1873,23 +1858,7 @@ jQuery.atmosphere = function() { clone.appendChild(cdoc.createTextNode(".")); var text = clone.innerText; - var isJunkEnded = true; - - if (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1) { - isJunkEnded = false; - } - - if (isJunkEnded) { - var endOfJunk = "<!-- EOD -->"; - var endOfJunkLength = endOfJunk.length; - var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength; - - text = text.substring(junkEnd); - } - text = text.substring(0, text.length - 1); - - _handleProtocol(rq, text); return text; }; @@ -1918,11 +1887,14 @@ jQuery.atmosphere = function() { var text = readResponse(); if (text.length > rq.lastIndex) { _response.status = 200; + _response.error = null; - // Empties response every time that it is handled - res.innerText = ""; - _prepareCallback(text, "messageReceived", 200, rq.transport); - + var message = text; + if (message.length != 0 && _handleProtocol(rq, message)) { + // Empties response every time that it is handled + res.innerText = ""; + _prepareCallback(message, "messageReceived", 200, rq.transport); + } rq.lastIndex = 0; } @@ -1938,12 +1910,13 @@ jQuery.atmosphere = function() { return false; } catch (err) { + _response.error = true; if (_requestCount++ < rq.maxReconnectOnClose) { rq.id = setTimeout(function() { _ieStreaming(rq); }, rq.reconnectInterval); } else { - _onError(); + _onError(0, "maxReconnectOnClose reached"); } doc.execCommand("Stop"); doc.close(); @@ -2095,6 +2068,7 @@ jQuery.atmosphere = function() { attachHeadersAsQueryString: true, enableXDR: _request.enableXDR, uuid : _request.uuid, + messageDelimiter : '|', enableProtocol : false, maxReconnectOnClose : _request.maxReconnectOnClose }; @@ -2147,11 +2121,11 @@ jQuery.atmosphere = function() { } function _prepareCallback(messageBody, state, errorCode, transport) { - _response.responseBody = messageBody; + if (state == "messageReceived") { - if (_trackMessageSize(messageBody, _request, _response)) { - return; - } + if (_trackMessageSize(messageBody, _request, _response)) return; + } else { + _response.responseBody = messageBody; } _response.transport = transport; @@ -2225,6 +2199,14 @@ jQuery.atmosphere = function() { } } + function _invokeClose(wasOpen) { + _response.state = 'closed'; + _response.responseBody = ""; + _response.messages = []; + _response.status = !wasOpen ? 501 : 200; + _invokeCallback(); + } + /** * Invoke request callbacks. * @@ -2242,7 +2224,7 @@ jQuery.atmosphere = function() { _request.reconnect = _request.mrequest; var messages = (typeof(_response.responseBody) == 'string' && _request.trackMessageLength) ? - _response.responseBody.split(_request.messageDelimiter) : new Array(_response.responseBody); + (_response.messages.length>0 ? _response.messages : ['']) : new Array(_response.responseBody); for (var i = 0; i < messages.length; i++) { if (messages.length > 1 && messages[i].length == 0) { @@ -2250,13 +2232,8 @@ jQuery.atmosphere = function() { } _response.responseBody = jQuery.trim(messages[i]); - // Ugly see issue 400. - if (_response.responseBody.length == 0 && _response.transport == 'streaming' && _response.state == "messageReceived") { - var ua = navigator.userAgent.toLowerCase(); - var isAndroid = ua.indexOf("android") > -1; - if (isAndroid) { - continue; - } + if (_response.responseBody.length == 0 && _response.state == "messageReceived") { + continue; } _invokeFunction(_response); @@ -2289,16 +2266,52 @@ jQuery.atmosphere = function() { } /** + * + * @private + */ + function _verifyStreamingLength(ajaxRequest, rq){ + // Wait to be sure we have the full message before closing. + if (_response.partialMessage == "" && + (rq.transport == 'streaming') && + (ajaxRequest.responseText.length > rq.maxStreamingLength)) { + _response.messages = []; + _invokeClose(true); + _disconnect(); + _clearState(); + _reconnect(ajaxRequest, rq, true); + } + } + + /** + * Disconnect + * @private + */ + function _disconnect() { + if (_request.enableProtocol) { + var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + _request.uuid; + var url = _request.url.replace(/([?&])_=[^&]*/, query); + url = url + (url === _request.url ? (/\?/.test(_request.url) ? "&" : "?") + query : ""); + + if (_request.connectTimeout > -1) { + jQuery.ajax({url: url, async: false, timeout: _request.connectTimeout}); + } else { + jQuery.ajax({url: url, async: false}); + } + } + } + + /** * Close request. * * @private */ function _close() { - _abordingConnection = true; _request.reconnect = false; + _abordingConnection = true; _response.request = _request; _response.state = 'unsubscribe'; _response.responseBody = ""; + _response.messages = []; _response.status = 408; _invokeCallback(); @@ -2319,7 +2332,9 @@ jQuery.atmosphere = function() { _activeRequest = null; } if (_websocket != null) { - _websocket.close(); + if (_websocket.webSocketOpened) { + _websocket.close(); + } _websocket = null; } if (_sse != null) { @@ -2343,7 +2358,7 @@ jQuery.atmosphere = function() { if (_localStorageService != null) { _localStorageService.close(); } - } + }; this.subscribe = function(options) { _subscribe(options); @@ -2362,6 +2377,10 @@ jQuery.atmosphere = function() { _close(); }; + this.disconnect = function () { + _disconnect(); + }; + this.getUrl = function() { return _request.url; }; @@ -2421,10 +2440,8 @@ jQuery.atmosphere = function() { var requestsClone = [].concat(jQuery.atmosphere.requests); for (var i = 0; i < requestsClone.length; i++) { var rq = requestsClone[i]; + rq.disconnect(); rq.close(); - if (rq.enableProtocol()) { - jQuery.ajax({url: this._closeUrl(rq), async:false}); - } clearTimeout(rq.response.request.id); } } @@ -2432,12 +2449,6 @@ jQuery.atmosphere = function() { jQuery.atmosphere.callbacks = []; }, - _closeUrl : function(rq) { - var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + rq.getUUID(); - var url = rq.getUrl().replace(/([?&])_=[^&]*/, query); - return url + (url === rq.getUrl() ? (/\?/.test(rq.getUrl()) ? "&" : "?") + query : ""); - }, - unsubscribeUrl: function(url) { var idx = -1; if (jQuery.atmosphere.requests.length > 0) { @@ -2446,10 +2457,8 @@ jQuery.atmosphere = function() { // Suppose you can subscribe once to an url if (rq.getUrl() == url) { + rq.disconnect(); rq.close(); - if (rq.enableProtocol()) { - jQuery.ajax({url :this._closeUrl(rq), async:false}); - } clearTimeout(rq.response.request.id); idx = i; break; @@ -2643,8 +2652,8 @@ jQuery.atmosphere = function() { /* * jQuery stringifyJSON * http://github.com/flowersinthesand/jquery-stringifyJSON - * - * Copyright 2011, Donghwan Kim + * + * Copyright 2011, Donghwan Kim * Licensed under the Apache License, Version 2.0 * http://www.apache.org/licenses/LICENSE-2.0 */ @@ -2728,4 +2737,4 @@ jQuery.atmosphere = function() { return str("", {"": value}); }; -}(jQuery));
\ No newline at end of file +}(jQuery)); |