/** * Initialize an {@link AtmosphereResource}. * * @param config The {@link org.atmosphere.cpr.AtmosphereConfig} * @param broadcaster The {@link org.atmosphere.cpr.Broadcaster}. * @param req The {@link AtmosphereRequest} * @param response The {@link AtmosphereResource} * @param asyncSupport The {@link AsyncSupport} * @param atmosphereHandler The {@link AtmosphereHandler} * @return this */ @Override public AtmosphereResource initialize( AtmosphereConfig config, Broadcaster broadcaster, AtmosphereRequest req, AtmosphereResponse response, AsyncSupport asyncSupport, AtmosphereHandler atmosphereHandler) { this.req = req; this.response = response; this.broadcaster = broadcaster; this.config = config; this.asyncSupport = asyncSupport; this.atmosphereHandler = atmosphereHandler; this.event = new AtmosphereResourceEventImpl(this); String s = (String) req.getAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID); if (s == null) { s = response.getHeader(HeaderConfig.X_ATMOSPHERE_TRACKING_ID); } uuid = s == null ? UUID.randomUUID().toString() : s; if (config.isSupportSession()) { // Keep a reference to an HttpSession in case the associated request get recycled by the // underlying container. try { session = req.getSession(true); } catch (NullPointerException ex) { // http://java.net/jira/browse/GLASSFISH-18856 logger.trace("http://java.net/jira/browse/GLASSFISH-18856", ex); } } transport = configureTransport(); return this; }
@Override public HttpSession session(boolean create) { if (config.isSupportSession() && session == null) { // http://java.net/jira/browse/GLASSFISH-18856 session = req.getSession(create); } return session; }
@Override public AtmosphereResource suspend(long timeout) { if (event.isSuspended() || disableSuspend) return this; if (config.isSupportSession() && req.getSession(false) != null && req.getSession().getMaxInactiveInterval() != -1 && req.getSession().getMaxInactiveInterval() * 1000 < timeout) { throw new IllegalStateException( "Cannot suspend a " + "response longer than the session timeout. Increase the value of session-timeout in web.xml"); } if (transport().equals(TRANSPORT.JSONP) || transport().equals(TRANSPORT.LONG_POLLING)) { resumeOnBroadcast.set(true); } onPreSuspend(event); // Recheck based on preSuspend if (event.isSuspended() || disableSuspend) return this; if (!event.isResumedOnTimeout()) { Enumeration<String> connection = req.getHeaders("Connection"); if (connection == null) { connection = req.getHeaders("connection"); } if (connection != null && connection.hasMoreElements()) { String[] e = connection.nextElement().toString().split(","); for (String upgrade : e) { if (upgrade.trim().equalsIgnoreCase(WEBSOCKET_UPGRADE)) { if (!asyncSupport.supportWebSocket()) { response.addHeader(X_ATMOSPHERE_ERROR, "Websocket protocol not supported"); } else { req.setAttribute(FrameworkConfig.TRANSPORT_IN_USE, HeaderConfig.WEBSOCKET_TRANSPORT); } } } } if (req.getHeader(X_ATMOSPHERE_TRANSPORT) == null) { req.setAttribute(FrameworkConfig.TRANSPORT_IN_USE, HeaderConfig.LONG_POLLING_TRANSPORT); } req.setAttribute(PRE_SUSPEND, "true"); action.type(Action.TYPE.SUSPEND); action.timeout(timeout); // TODO: We can possibly optimize that call by avoiding creating a Broadcaster if we are sure // the Broadcaster // is unique. boolean isJersey = req.getAttribute(FrameworkConfig.CONTAINER_RESPONSE) != null; boolean skipCreation = false; if (req.getAttribute(SKIP_BROADCASTER_CREATION) != null) { skipCreation = true; } // Null means SCOPE=REQUEST set by a Meteor if (!skipCreation && (broadcaster == null || broadcaster.getScope() == Broadcaster.SCOPE.REQUEST) && !isJersey) { String id = broadcaster != null ? broadcaster.getID() : getClass().getName(); Class<? extends Broadcaster> clazz = broadcaster != null ? broadcaster.getClass() : DefaultBroadcaster.class; broadcaster = config.getBroadcasterFactory().lookup(clazz, id, false); if (broadcaster == null || broadcaster.getAtmosphereResources().size() > 0) { broadcaster = config.getBroadcasterFactory().lookup(clazz, id + "/" + UUID.randomUUID(), true); } } broadcaster.addAtmosphereResource(this); if (req.getAttribute(DefaultBroadcaster.CACHED) != null && transport() != null && (transport().equals(TRANSPORT.LONG_POLLING) || transport().equals(TRANSPORT.JSONP))) { action.type(Action.TYPE.CONTINUE); // Do nothing because we have found cached message which was written already, and the // handler resumed. logger.debug("Cached message found, not suspending {}", uuid()); return this; } req.removeAttribute(PRE_SUSPEND); notifyListeners(); } return this; }
/** * Is {@link HttpSession} supported * * @return true if supported */ protected boolean supportSession() { return config.isSupportSession(); }