@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());
    }
  }
Example #2
0
  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());
    }
  }
Example #3
0
  @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();
      }
    }
  }
Example #6
0
    @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();
        }
      }
    }
  }