_request.ctime = jQuery.now();
if (_request.transport != 'websocket' && _request.transport != 'sse') {
- // Gives a chance to the connection to be established before calling the callback
- setTimeout(function() {
- _open('opening', _request.transport, _request);
- }, 500);
_executeRequest();
-
} else if (_request.transport == 'websocket') {
if (!_supportWebsocket()) {
_reconnectWithFallbackTransport("Websocket is not supported, using request.fallbackTransport (" + _request.fallbackTransport + ")");
_close();
};
+ request.closed = false;
+
if (_response.error == null) {
_response.request = request;
var prevState = _response.state;
jQuery.atmosphere.debug("Using URL: " + location);
}
- if (webSocketOpened) {
- _open('re-opening', "websocket", _request);
- }
-
if (webSocketOpened && !_request.reconnect) {
if (_websocket != null) {
_clearState();
jQuery.atmosphere.debug("Websocket successfully opened");
}
- if (!webSocketOpened) {
- _open('opening', "websocket", _request);
- }
+ _open('opening', 'websocket', _request);
webSocketOpened = true;
_websocket.webSocketOpened = webSocketOpened;
if (_abordingConnection) {
return;
}
+
_response.error = null;
var skipCallbackInvocation = false;
var update = false;
+ if (rq.transport == 'streaming' && ajaxRequest.readyState == 2) {
+ _open('opening', rq.transport, rq);
+ }
// Opera doesn't call onerror if the server disconnect.
if (jQuery.browser.opera
// Prevent onerror callback to be called
_response.errorHandled = true;
_clearState();
+ _invokeClose(true);
reconnectF();
return;
}
}
_verifyStreamingLength(ajaxRequest, rq);
+
+ if (rq.transport == 'streaming' && rq.readyState == 4) {
+ _invokeClose(true);
+ reconnectF();
+ }
}
};
ajaxRequest.send(rq.data);
_response.status = status == 0 ? 204 : status;
_response.reason = status == 0 ? "Server resumed the connection or down." : "OK";
- var reconnectInterval = (request.connectTimeout == -1) ? 0 : request.connectTimeout;
+ var reconnectInterval = request.reconnectInterval;
// Reconnect immedialtely
- if (!force) {
- request.id = setTimeout(function () {
- _executeRequest(request);
- }, reconnectInterval);
- } else {
+ request.id = setTimeout(function () {
_executeRequest(request);
- }
+ }, reconnectInterval);
}
}
}
message = message.substring(9, message.length() - 1);
connection.handlePushMessage(message);
}
+
+ if (!connection.isApplicationRunning()) {
+ disconnect(new Command() {
+ @Override
+ public void execute() {
+ }
+ });
+ }
}
/**
* the connection until successful.
*
*/
- protected void onError() {
- VConsole.error("Push connection using " + getConfig().getTransport()
- + " failed!");
+ protected void onError(AtmosphereResponse response) {
+ state = State.DISCONNECTED;
+ errorHandler.onError("Push connection using "
+ + getConfig().getTransport() + " failed!",
+ response.getStatusCode());
+ }
+
+ protected void onClose(AtmosphereResponse response) {
+ VConsole.log("Push connection closed, awaiting reconnection");
+ state = State.CONNECT_PENDING;
+ }
+
+ protected void onReconnect(JavaScriptObject request,
+ final AtmosphereResponse response) {
+ VConsole.log("Reopening push connection");
}
public static abstract class AbstractJSO extends JavaScriptObject {
}
+ public final int getStatusCode() {
+ return getIntValue("status");
+ }
+
public final String getResponseBody() {
return getStringValue("responseBody");
}
transport: 'websocket',
fallbackTransport: 'streaming',
contentType: 'application/json; charset=UTF-8',
- reconnectInterval: '5000',
+ reconnectInterval: 5000,
maxReconnectOnClose: 10000000,
trackMessageLength: true,
messageDelimiter: String.fromCharCode(@com.vaadin.shared.communication.PushConstants::MESSAGE_DELIMITER)
self.@com.vaadin.client.communication.AtmospherePushConnection::onMessage(*)(response);
});
config.onError = $entry(function(response) {
- self.@com.vaadin.client.communication.AtmospherePushConnection::onError()(response);
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onError(*)(response);
});
config.onTransportFailure = $entry(function(reason,request) {
self.@com.vaadin.client.communication.AtmospherePushConnection::onTransportFailure(*)(reason);
});
+ config.onClose = $entry(function(response) {
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onClose(*)(response);
+ });
+ config.onReconnect = $entry(function(request, response) {
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onReconnect(*)(request, response);
+ });
return $wnd.jQueryVaadin.atmosphere.subscribe(config);
}-*/;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResource.TRANSPORT;
import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter;
import org.json.JSONException;
import com.vaadin.server.LegacyCommunicationManager.InvalidUIDLSecurityKeyException;
* @author Vaadin Ltd
* @since 7.1
*/
-public class PushHandler implements AtmosphereHandler {
+public class PushHandler extends AtmosphereResourceEventListenerAdapter
+ implements AtmosphereHandler {
/**
* Callback interface used internally to process an event with the
* open by calling resource.suspend(). If there is a pending push, send it
* now.
*/
- private static PushEventCallback establishCallback = new PushEventCallback() {
+ private final PushEventCallback establishCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
getLogger().log(Level.FINER,
"New push connection with transport {0}",
resource.transport());
+
+ resource.addEventListener(PushHandler.this);
+
resource.getResponse().setContentType("text/plain; charset=UTF-8");
VaadinSession session = ui.getSession();
* the request and send changed UI state via the push channel (we do not
* respond to the request directly.)
*/
- private static PushEventCallback receiveCallback = new PushEventCallback() {
+ private final PushEventCallback receiveCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
+ getLogger().log(Level.FINER, "Received message from resource {0}",
+ resource.uuid());
+
AtmosphereRequest req = resource.getRequest();
AtmospherePushConnection connection = getConnectionForUI(ui);
/**
* Callback used when a connection is closed by the client.
*/
- PushEventCallback disconnectCallback = new PushEventCallback() {
+ private final PushEventCallback disconnectCallback = new PushEventCallback() {
@Override
public void run(AtmosphereResource resource, UI ui) throws IOException {
PushMode pushMode = ui.getPushConfiguration().getPushMode();
* mode has been set to disabled, just clean up some stuff
* and be done with it
*/
- getLogger().log(Level.FINEST,
+ getLogger().log(Level.FINER,
"Connection closed for resource {0}", id);
} else {
/*
* tab.
*/
getLogger()
- .log(Level.FINE,
+ .log(Level.FINER,
"Connection unexpectedly closed for resource {0} with transport {1}",
new Object[] { id, resource.transport() });
}
String id = resource.uuid();
if (event.isCancelled()) {
- callWithUi(resource, disconnectCallback);
+ // Disconnected for whatever reason, handle in onDisconnect() as
+ // it's more reliable
} else if (event.isResuming()) {
// A connection that was suspended earlier was resumed (committed to
// the client.) Should only happen if the transport is JSONP or
}
}
+ @Override
+ public void onDisconnect(AtmosphereResourceEvent event) {
+ // Log event on trace level
+ super.onDisconnect(event);
+ callWithUi(event.getResource(), disconnectCallback);
+ }
+
@Override
public void destroy() {
}