void invokeAtmosphereHandler(AtmosphereResourceImpl r) throws IOException { if (!r.isInScope()) return; AtmosphereRequest req = r.getRequest(false); String disableOnEvent = r.getAtmosphereConfig().getInitParameter(ApplicationConfig.DISABLE_ONSTATE_EVENT); try { if (disableOnEvent == null || !disableOnEvent.equals(String.valueOf(true))) { AtmosphereHandler atmosphereHandler = (AtmosphereHandler) req.getAttribute(FrameworkConfig.ATMOSPHERE_HANDLER); synchronized (r) { atmosphereHandler.onStateChange(r.getAtmosphereResourceEvent()); Meteor m = (Meteor) req.getAttribute(AtmosphereResourceImpl.METEOR); if (m != null) { m.destroy(); } } req.removeAttribute(FrameworkConfig.ATMOSPHERE_RESOURCE); } } catch (IOException ex) { try { r.onThrowable(ex); } catch (Throwable t) { logger.warn("failed calling onThrowable()", ex); } } }
/** * Note: Filter does not delegate to chain, since it would lead into cycle by calling {@link * PushServlet#service(ServletRequest, ServletResponse)}. */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { HttpServletRequest httpReq = (HttpServletRequest) request; HttpServletResponse httpResp = (HttpServletResponse) response; if ("GET".equals(httpReq.getMethod())) { String pushSessionId = httpReq.getParameter(PUSH_SESSION_ID_PARAM); Session session = null; if (pushSessionId != null) { ensureServletContextAvailable(request); PushContext pushContext = (PushContext) servletContext.getAttribute(PushContext.INSTANCE_KEY_NAME); session = pushContext.getSessionManager().getPushSession(pushSessionId); } if (session == null) { if (LOGGER.isDebugEnabled()) { LOGGER.debug(MessageFormat.format("Session {0} was not found", pushSessionId)); } httpResp.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } httpResp.setContentType("text/plain"); Meteor meteor = Meteor.build(httpReq, SCOPE.REQUEST, Collections.<BroadcastFilter>emptyList(), null); try { Request pushRequest = new RequestImpl(meteor, session); httpReq.setAttribute(SESSION_ATTRIBUTE_NAME, session); httpReq.setAttribute(REQUEST_ATTRIBUTE_NAME, pushRequest); pushRequest.suspend(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); } return; } } }
@Override public AtmosphereResource resume() { if (!isSuspended()) { logger.warn("AtmosphereResource {} not suspend, cannot resume it.", uuid()); return this; } try { if (!isResumed.getAndSet(true) && isInScope.get()) { logger.trace("AtmosphereResource {} is resuming", uuid()); action.type(Action.TYPE.RESUME); // We need it as Jetty doesn't support timeout Broadcaster b = getBroadcaster(false); if (!b.isDestroyed() && b instanceof DefaultBroadcaster) { ((DefaultBroadcaster) b).broadcastOnResume(this); } notifyListeners(); try { if (!b.isDestroyed()) { broadcaster.removeAtmosphereResource(this); } } catch (IllegalStateException ex) { logger.warn("Unable to resume", this); logger.debug(ex.getMessage(), ex); } if (b.getScope() == Broadcaster.SCOPE.REQUEST) { logger.debug("Broadcaster's scope is set to request, destroying it {}", b.getID()); b.destroy(); } // Resuming here means we need to pull away from all other Broadcaster, if they exists. if (config.getBroadcasterFactory() != null) { config.getBroadcasterFactory().removeAllAtmosphereResource(this); } try { req.setAttribute(ApplicationConfig.RESUMED_ON_TIMEOUT, Boolean.FALSE); } catch (Exception ex) { logger.debug("Resume exception: Cannot resume an already resumed/cancelled request", ex); } finally { try { Meteor m = (Meteor) req.getAttribute(METEOR); if (m != null) { m.destroy(); } } catch (Exception ex) { logger.debug( "Meteor resume exception: Cannot resume an already resumed/cancelled request", ex); } } if (req.getAttribute(PRE_SUSPEND) == null) { asyncSupport.action(this); } } else { logger.trace("Already resumed {}", this); return this; } } catch (Throwable t) { logger.trace("Wasn't able to resume a connection {}", this, t); } listeners.clear(); return this; }
/** {@inheritDoc} */ @Override public synchronized AtmosphereResource resume() { // We need to synchronize the method because the resume may occurs at the same time a message is // published // and we will miss that message. The DefaultBroadcaster synchronize on that method before // writing a message. try { if (!isResumed && isInScope) { action.type(Action.TYPE.RESUME); isResumed = true; // We need it as Jetty doesn't support timeout Broadcaster b = getBroadcaster(false); if (!b.isDestroyed() && b instanceof DefaultBroadcaster) { ((DefaultBroadcaster) b).broadcastOnResume(this); } notifyListeners(); try { if (!b.isDestroyed()) { broadcaster.removeAtmosphereResource(this); } } catch (IllegalStateException ex) { logger.warn("Unable to resume", this); logger.debug(ex.getMessage(), ex); } if (b.getScope() == Broadcaster.SCOPE.REQUEST) { logger.debug("Broadcaster's scope is set to request, destroying it {}", b.getID()); b.destroy(); } // Resuming here means we need to pull away from all other Broadcaster, if they exists. if (config.getBroadcasterFactory() != null) { config.getBroadcasterFactory().removeAllAtmosphereResource(this); } try { req.setAttribute(ApplicationConfig.RESUMED_ON_TIMEOUT, Boolean.FALSE); } catch (Exception ex) { logger.debug("Resume exception: Cannot resume an already resumed/cancelled request", ex); } finally { try { Meteor m = (Meteor) req.getAttribute(METEOR); if (m != null) { m.destroy(); } } catch (Exception ex) { logger.debug( "Meteor resume exception: Cannot resume an already resumed/cancelled request", ex); } } if (req.getAttribute(PRE_SUSPEND) == null) { asyncSupport.action(this); } } else { logger.debug("Cannot resume an already resumed/cancelled request {}", this); } } catch (Throwable t) { logger.trace("Wasn't able to resume a connection {}", this, t); } notifyListeners(new AtmosphereResourceEventImpl(this, true, false)); listeners.clear(); return this; }
public static Meteor getMeteor(HttpServletRequest request) { return Meteor.build(request); }