/** * Find the UI for the atmosphere resource, lock it and invoke the callback. * * @param resource the atmosphere resource for the current request * @param callback the push callback to call when a UI is found and locked */ private void callWithUi(final AtmosphereResource resource, final PushEventCallback callback) { AtmosphereRequest req = resource.getRequest(); VaadinServletRequest vaadinRequest = new VaadinServletRequest(req, service); VaadinSession session = null; service.requestStart(vaadinRequest, null); try { try { session = service.findVaadinSession(vaadinRequest); } catch (ServiceException e) { getLogger().log(Level.SEVERE, "Could not get session. This should never happen", e); } catch (SessionExpiredException e) { SystemMessages msg = service.getSystemMessages( ServletPortletHelper.findLocale(null, null, vaadinRequest), vaadinRequest); try { resource .getResponse() .getWriter() .write( VaadinService.createCriticalNotificationJSON( msg.getSessionExpiredCaption(), msg.getSessionExpiredMessage(), null, msg.getSessionExpiredURL())); } catch (IOException e1) { getLogger().log(Level.WARNING, "Failed to notify client about unavailable session", e); } return; } session.lock(); try { VaadinSession.setCurrent(session); // Sets UI.currentInstance final UI ui = service.findUI(vaadinRequest); if (ui == null) { // This a request through an already open push connection to // a UI which no longer exists. resource .getResponse() .getWriter() .write(UidlRequestHandler.getUINotFoundErrorJSON(service, vaadinRequest)); // End the connection resource.resume(); return; } callback.run(resource, ui); } catch (IOException e) { getLogger().log(Level.INFO, "An error occured while writing a push response", e); } finally { session.unlock(); } } finally { service.requestEnd(vaadinRequest, null, session); } }
/** * Sends a refresh message to the given atmosphere resource. Uses an AtmosphereResource instead of * an AtmospherePushConnection even though it might be possible to look up the * AtmospherePushConnection from the UI to ensure border cases work correctly, especially when * there temporarily are two push connections which try to use the same UI. Using the * AtmosphereResource directly guarantees the message goes to the correct recipient. * * @param resource The atmosphere resource to send refresh to */ private static void sendRefreshAndDisconnect(AtmosphereResource resource) throws IOException { AtmospherePushConnection connection = new AtmospherePushConnection(null); connection.connect(resource); connection.sendMessage(VaadinService.createCriticalNotificationJSON(null, null, null, null)); connection.disconnect(); }