private void disconnect(AtmosphereResourceEvent event) {
// We don't want to use callWithUi here, as it assumes there's a client
// request active and does requestStart and requestEnd among other
// things.
AtmosphereResource resource = event.getResource();
VaadinServletRequest vaadinRequest = new VaadinServletRequest(
resource.getRequest(), service);
VaadinSession session = null;
try {
session = service.findVaadinSession(vaadinRequest);
} catch (ServiceException e) {
getLogger().log(Level.SEVERE,
"Could not get session. This should never happen", e);
return;
} catch (SessionExpiredException e) {
getLogger()
.log(Level.SEVERE,
"Session expired before push was disconnected. This should never happen",
e);
return;
}
UI ui = null;
session.lock();
try {
VaadinSession.setCurrent(session);
// Sets UI.currentInstance
ui = service.findUI(vaadinRequest);
if (ui == null) {
/*
* UI not found, could be because FF has asynchronously closed
* the websocket connection and Atmosphere has already done
* cleanup of the request attributes.
*
* In that case, we still have a chance of finding the right UI
* by iterating through the UIs in the session looking for one
* using the same AtmosphereResource.
*/
ui = findUiUsingResource(resource, session.getUIs());
if (ui == null) {
getLogger()
.log(Level.SEVERE,
"Could not get UI. This should never happen,"
+ " except when reloading in Firefox -"
+ " see http://dev.vaadin.com/ticket/14251.");
return;
} else {
getLogger()
.log(Level.INFO,
"No UI was found based on data in the request,"
+ " but a slower lookup based on the AtmosphereResource succeeded."
+ " See http://dev.vaadin.com/ticket/14251 for more details.");
}
}
PushMode pushMode = ui.getPushConfiguration().getPushMode();
AtmospherePushConnection pushConnection = getConnectionForUI(ui);
String id = resource.uuid();
if (pushConnection == null) {
getLogger()
.log(Level.WARNING,
"Could not find push connection to close: {0} with transport {1}",
new Object[] { id, resource.transport() });
} else {
if (!pushMode.isEnabled()) {
/*
* The client is expected to close the connection after push
* mode has been set to disabled.
*/
getLogger().log(Level.FINER,
"Connection closed for resource {0}", id);
} else {
/*
* Unexpected cancel, e.g. if the user closes the browser
* tab.
*/
getLogger()
.log(Level.FINER,
"Connection unexpectedly closed for resource {0} with transport {1}",
new Object[] { id, resource.transport() });
}
if (pushConnection.isConnected()) {
// disconnect() assumes the push connection is connected but
// this method can currently be called more than once during
// disconnect, depending on the situation