@Override public void onStateChange(AtmosphereResourceEvent event) throws IOException { AtmosphereResource r = event.getResource(); AtmosphereResponse res = r.getResponse(); if (event.isSuspended()) { String body = event.getMessage().toString(); ChatData data = new Gson().fromJson(body, ChatData.class); res.getWriter().write(new ChatData(data.getAuthor(), data.getText()).toString()); switch (r.transport()) { case JSONP: case AJAX: case LONG_POLLING: event.getResource().resume(); break; default: res.getWriter().flush(); break; } } else if (!event.isResuming()) { event.broadcaster().broadcast(new ChatData("Someone", "say bye bye!").toString()); } }
public void onThrowable(AtmosphereResourceEvent event) { // called when a push connection is broken try { JSONObject dim = (JSONObject) event.getMessage(); internalNotifySchedule.pushNotAtendedNotification(dim); logger.info("Sending again the Notification: " + dim); } catch (Exception e) { logger.debug("Not correct message!"); } event.broadcaster().destroy(); internalNotifySchedule.removeBroadcaster(event.broadcaster()); if (logger.isDebugEnabled()) { logger.error("Atmosphere connection broken: " + event); } else { logger.warn("Atmosphere connection broken: " + event.getMessage()); } }
@Override public void onStateChange(AtmosphereResourceEvent event) throws IOException { AtmosphereResource resource = event.getResource(); String id = resource.uuid(); if (event.isCancelled()) { callWithUi(resource, disconnectCallback); } else if (event.isResuming()) { // A connection that was suspended earlier was resumed (committed to // the client.) Should only happen if the transport is JSONP or // long-polling. getLogger().log(Level.FINER, "Resuming request for resource {0}", id); } else { // A message was broadcast to this resource and should be sent to // the client. We don't do any actual broadcasting, in the sense of // sending to multiple recipients; any UIDL message is specific to a // single client. getLogger().log(Level.FINER, "Writing message to resource {0}", id); Writer writer = resource.getResponse().getWriter(); writer.write(event.getMessage().toString()); switch (resource.transport()) { case WEBSOCKET: break; case SSE: case STREAMING: writer.flush(); break; case JSONP: case LONG_POLLING: resource.resume(); break; default: getLogger().log(Level.SEVERE, "Unknown transport {0}", resource.transport()); } } }
@Override public void onBroadcast(AtmosphereResourceEvent event) { System.out.println("onBroadcast(): {}" + event.getMessage()); }
/** * Write the {@link AtmosphereResourceEvent#getMessage()} back to the client using the {@link * org.atmosphere.cpr.AtmosphereResponse#getOutputStream()} or {@link * org.atmosphere.cpr.AtmosphereResponse#getWriter()}. If a {@link org.atmosphere.cpr.Serializer} * is defined, it will be invoked and the writ operation will be delegated to to it. * * <p>By default, this method will try to use {@link * org.atmosphere.cpr.AtmosphereResponse#getWriter()}. * * @param event the {@link AtmosphereResourceEvent#getMessage()} * @throws java.io.IOException */ public void onStateChange(AtmosphereResourceEvent event) throws IOException { Object message = event.getMessage(); AtmosphereResponse r = event.getResource().getResponse(); if (message == null || event.isCancelled() || event.getResource().getRequest().destroyed()) return; if (event.getResource().getSerializer() != null) { try { event .getResource() .getSerializer() .write(event.getResource().getResponse().getOutputStream(), message); } catch (Throwable ex) { logger.warn("Serializer exception: message: " + message, ex); throw new IOException(ex); } } else { boolean isUsingStream = (Boolean) event.getResource().getRequest().getAttribute(PROPERTY_USE_STREAM); if (!isUsingStream) { try { r.getWriter(); } catch (IllegalStateException e) { isUsingStream = true; } } if (message instanceof List) { for (String s : (List<String>) message) { if (isUsingStream) { r.getOutputStream().write(s.getBytes(r.getCharacterEncoding())); r.getOutputStream().flush(); } else { r.getWriter().write(s); r.getWriter().flush(); } } } else { if (isUsingStream) { r.getOutputStream().write(message.toString().getBytes(r.getCharacterEncoding())); r.getOutputStream().flush(); } else { r.getWriter().write(message.toString()); r.getWriter().flush(); } } Boolean resumeOnBroadcast = event.getResource().resumeOnBroadcast(); if (!resumeOnBroadcast) { // For legacy reason, check the attribute as well Object o = event.getResource().getRequest().getAttribute(ApplicationConfig.RESUME_ON_BROADCAST); if (o != null && Boolean.class.isAssignableFrom(o.getClass())) { resumeOnBroadcast = Boolean.class.cast(o); } } if (resumeOnBroadcast != null && resumeOnBroadcast) { event.getResource().resume(); } } }
@Override public void onStateChange(AtmosphereResourceEvent event) throws IOException { AtmosphereResponse response = event.getResource().getResponse(); AtmosphereResource resource = event.getResource(); if (event.isSuspended()) { // Set content type before do response.getWriter() // http://docs.oracle.com/javaee/5/api/javax/servlet/ServletResponse.html#setContentType(java.lang.String) response.setContentType("text/plain; charset=UTF-8"); response.setCharacterEncoding("UTF-8"); if (event.getMessage().getClass().isArray()) { LOG.fine("SEND MESSAGE ARRAY " + event.getMessage().toString()); List<Object> list = Arrays.asList(event.getMessage()); response.getOutputStream().write(MSG_SEPARATOR.getBytes(MSG_CHARSET)); for (Object object : list) { String message = (String) object; message += MSG_SEPARATOR; response.getOutputStream().write(message.getBytes(MSG_CHARSET)); } } else if (event.getMessage() instanceof List) { LOG.fine("SEND MESSAGE LIST " + event.getMessage().toString()); @SuppressWarnings("unchecked") List<Object> list = List.class.cast(event.getMessage()); response.getOutputStream().write(MSG_SEPARATOR.getBytes(MSG_CHARSET)); for (Object object : list) { String message = (String) object; message += MSG_SEPARATOR; response.getOutputStream().write(message.getBytes(MSG_CHARSET)); } } else if (event.getMessage() instanceof String) { LOG.fine("SEND MESSAGE " + event.getMessage().toString()); String message = (String) event.getMessage(); response.getOutputStream().write(message.getBytes(MSG_CHARSET)); } try { response.flushBuffer(); switch (resource.transport()) { case JSONP: case LONG_POLLING: event.getResource().resume(); break; case WEBSOCKET: case STREAMING: case SSE: response.getOutputStream().flush(); break; default: LOG.info("Unknown transport"); break; } } catch (IOException e) { LOG.info("Error resuming resource response", e); } } else if (event.isResuming()) { LOG.fine("RESUMING"); } else if (event.isResumedOnTimeout()) { LOG.fine("RESUMED ON TIMEOUT"); } else if (event.isClosedByApplication() || event.isClosedByClient()) { LOG.fine("CONNECTION CLOSED"); AtmosphereResourceSession resourceSession = AtmosphereResourceSessionFactory.getDefault().getSession(resource); AtmosphereChannel resourceChannel = resourceSession.getAttribute(WAVE_CHANNEL_ATTRIBUTE, AtmosphereChannel.class); if (resourceChannel != null) { resourceChannel.onDisconnect(); } } }
public static final void broadcast( final AtmosphereResource r, final AtmosphereResourceEvent e, final Broadcaster broadcaster) { AtmosphereRequest request = r.getRequest(); ContainerResponse cr = null; // Make sure only one thread can play with the ContainerResponse. Threading issue can arise if // there is a scheduler // or if ContainerResponse is associated with more than Broadcaster. cr = (ContainerResponse) request.getAttribute(FrameworkConfig.CONTAINER_RESPONSE); if (cr == null || !r.isSuspended() && !r.getAtmosphereResourceEvent().isResumedOnTimeout()) { if (cr == null) { logger.warn( "Unexpected state. ContainerResponse has been resumed. Caching message {} for {}", e.getMessage(), r.uuid()); } else { logger.warn("The AtmosphereResource {} hasn't been suspended yet.", r.uuid(), e); } if (DefaultBroadcaster.class.isAssignableFrom(broadcaster.getClass())) { DefaultBroadcaster.class.cast(broadcaster).cacheLostMessage(r, true); } AtmosphereResourceImpl.class.cast(r)._destroy(); return; } synchronized (cr) { try { // This is required when you change the response's type String m = null; if (request.getAttribute(FrameworkConfig.EXPECTED_CONTENT_TYPE) != null) { m = (String) request.getAttribute(FrameworkConfig.EXPECTED_CONTENT_TYPE); } if (m == null || m.equalsIgnoreCase("text/event-stream")) { if (cr.getHttpHeaders().getFirst(HttpHeaders.CONTENT_TYPE) != null) { m = cr.getHttpHeaders().getFirst(HttpHeaders.CONTENT_TYPE).toString(); } if (m == null || m.equalsIgnoreCase("application/octet-stream")) { m = r.getAtmosphereConfig().getInitParameter(ApplicationConfig.SSE_CONTENT_TYPE); if (m == null) { m = "text/plain"; } } } if (e.getMessage() instanceof Response) { cr.setResponse((Response) e.getMessage()); cr.getHttpHeaders().add(HttpHeaders.CONTENT_TYPE, m); cr.write(); try { cr.getOutputStream().flush(); } catch (IOException ex) { logger.trace("", ex); } } else if (e.getMessage() instanceof List) { for (Object msg : (List<Object>) e.getMessage()) { cr.setResponse(Response.ok(msg).build()); cr.getHttpHeaders().add(HttpHeaders.CONTENT_TYPE, m); cr.write(); } // https://github.com/Atmosphere/atmosphere/issues/169 try { cr.getOutputStream().flush(); } catch (IOException ex) { logger.trace("", ex); } } else { if (e.getMessage() == null) { logger.warn("Broadcasted message is null"); return; } cr.setResponse(Response.ok(e.getMessage()).build()); cr.getHttpHeaders().add(HttpHeaders.CONTENT_TYPE, m); cr.write(); try { cr.getOutputStream().flush(); } catch (IOException ex) { logger.trace("", ex); } } } catch (Throwable t) { boolean notifyAndCache = true; logger.trace( "Unexpected exception for AtmosphereResource {} and Broadcaster {}", r.uuid(), broadcaster.getID()); if (isJetty(r)) { for (StackTraceElement element : t.getStackTrace()) { if (element.getClassName().equals("java.io.BufferedWriter") && element.getMethodName().equals("flush")) { logger.trace("Workaround issue https://github.com/Atmosphere/atmosphere/issues/710"); notifyAndCache = false; } } } if (DefaultBroadcaster.class.isAssignableFrom(broadcaster.getClass())) { DefaultBroadcaster.class.cast(broadcaster).onException(t, r, notifyAndCache); } else { onException(t, r); } } finally { if (cr != null) { cr.setEntity(null); } Boolean resumeOnBroadcast = (Boolean) request.getAttribute(ApplicationConfig.RESUME_ON_BROADCAST); if (resumeOnBroadcast != null && resumeOnBroadcast) { String uuid = (String) request.getAttribute(AtmosphereFilter.RESUME_UUID); if (uuid != null) { if (request.getAttribute(AtmosphereFilter.RESUME_CANDIDATES) != null) { ((ConcurrentHashMap<String, AtmosphereResource>) request.getAttribute(AtmosphereFilter.RESUME_CANDIDATES)) .remove(uuid); } } r.getRequest().setAttribute(FrameworkConfig.CONTAINER_RESPONSE, null); r.resume(); } } } }