/** {@inheritDoc} */ public void setScope(SCOPE scope) { this.scope = scope; if (scope != SCOPE.REQUEST) { return; } try { for (AtmosphereResource<?, ?> resource : resources) { Broadcaster b = BroadcasterFactory.getDefault() .get(getClass(), getClass().getSimpleName() + "/" + UUID.randomUUID()); if (DefaultBroadcaster.class.isAssignableFrom(this.getClass())) { BroadcasterCache cache = bc.getBroadcasterCache().getClass().newInstance(); InjectorProvider.getInjector().inject(cache); DefaultBroadcaster.class.cast(b).broadcasterCache = cache; } resource.setBroadcaster(b); if (resource.getAtmosphereResourceEvent().isSuspended()) { b.addAtmosphereResource(resource); } } if (!resources.isEmpty()) { destroy(); } } catch (Exception e) { logger.error("failed to set request scope for current resources", e); } }
protected Broadcaster getBroadcaster(boolean autoCreate) { if (broadcaster == null) { throw new IllegalStateException("No Broadcaster associated with this AtmosphereResource."); } String s = config.getInitParameter(ApplicationConfig.RECOVER_DEAD_BROADCASTER); if (s != null) { autoCreate = Boolean.parseBoolean(s); } if (autoCreate && broadcaster.isDestroyed() && config.getBroadcasterFactory() != null) { logger.debug( "Broadcaster {} has been destroyed and cannot be re-used. Recreating a new one with the same name. You can turn off this" + " mechanism by adding, in web.xml, {} set to false", broadcaster.getID(), ApplicationConfig.RECOVER_DEAD_BROADCASTER); Broadcaster.SCOPE scope = broadcaster.getScope(); synchronized (this) { String id = scope != Broadcaster.SCOPE.REQUEST ? broadcaster.getID() : broadcaster.getID() + ".recovered" + UUID.randomUUID(); // Another Thread may have added the Broadcaster. broadcaster = config.getBroadcasterFactory().lookup(id, true); broadcaster.setScope(scope); broadcaster.addAtmosphereResource(this); } } return broadcaster; }
@Test public void findTest() { Broadcaster b1 = BroadcasterFactory.getDefault().get("b1"); Broadcaster b2 = BroadcasterFactory.getDefault().get("b2"); AtmosphereResource r = AtmosphereResourceFactory.getDefault() .create( mock(AtmosphereConfig.class), b1, AtmosphereResponse.newInstance().request(AtmosphereRequest.create()), mock(AsyncSupport.class), mock(AtmosphereHandler.class)); assertNotNull(r); b2.addAtmosphereResource(r); assertNotNull(AtmosphereResourceFactory.getDefault().find(r.uuid())); }
@BeforeMethod public void setUp() throws Exception { AtmosphereConfig config = new AtmosphereFramework().getAtmosphereConfig(); DefaultBroadcasterFactory factory = new DefaultBroadcasterFactory(ExcludeSessionBroadcaster.class, "NEVER", config); broadcaster = factory.get(ExcludeSessionBroadcaster.class, "test"); atmosphereHandler = new AR(); ar = new AtmosphereResourceImpl( config, broadcaster, mock(AtmosphereRequest.class), AtmosphereResponse.create(), mock(BlockingIOCometSupport.class), atmosphereHandler); broadcaster.addAtmosphereResource(ar); }
@Test public void deleteTest() { for (int i = 0; i < 10; i++) { BroadcasterFactory.getDefault().get(String.valueOf(i)); } Broadcaster b2 = BroadcasterFactory.getDefault().get("b2"); AtmosphereResource r = AtmosphereResourceFactory.getDefault() .create( mock(AtmosphereConfig.class), BroadcasterFactory.getDefault().lookup("1"), AtmosphereResponse.newInstance().request(AtmosphereRequest.create()), mock(AsyncSupport.class), mock(AtmosphereHandler.class)); assertNotNull(r); b2.addAtmosphereResource(r); assertNotNull(AtmosphereResourceFactory.getDefault().find(r.uuid())); assertEquals(AtmosphereResourceFactory.getDefault().remove(r.uuid()), r); assertNull(AtmosphereResourceFactory.getDefault().find(r.uuid())); }
@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; }