Search in sources :

Example 1 with HeartbeatAtmosphereResourceEvent

use of org.atmosphere.runtime.HeartbeatAtmosphereResourceEvent in project atmosphere by Atmosphere.

the class HeartbeatInterceptor method inspect.

@Override
public Action inspect(final AtmosphereResource r) {
    final AtmosphereResourceImpl impl = AtmosphereResourceImpl.class.cast(r);
    final AtmosphereRequest request = impl.getRequest(false);
    final AtmosphereResponse response = impl.getResponse(false);
    // Check heartbeat
    if (clientHeartbeatFrequencyInSeconds > 0) {
        byte[] body = new byte[0];
        try {
            if (!request.getMethod().equalsIgnoreCase("GET")) {
                body = IOUtils.readEntirelyAsByte(r);
            }
        } catch (IOException e) {
            logger.warn("", e);
            cancelF(request);
            return Action.CONTINUE;
        }
        if (Arrays.equals(paddingBytes, body)) {
            // Dispatch an event to notify that a heartbeat has been intercepted
            // TODO: see https://github.com/Atmosphere/atmosphere/issues/1561
            final AtmosphereResourceEvent event = new HeartbeatAtmosphereResourceEvent(AtmosphereResourceImpl.class.cast(r));
            if (AtmosphereResourceHeartbeatEventListener.class.isAssignableFrom(r.getAtmosphereHandler().getClass())) {
                r.addEventListener(new AtmosphereResourceEventListenerAdapter.OnHeartbeat() {

                    @Override
                    public void onHeartbeat(AtmosphereResourceEvent event) {
                        AtmosphereResourceHeartbeatEventListener.class.cast(r.getAtmosphereHandler()).onHeartbeat(event);
                    }
                });
            }
            // Fire event
            r.notifyListeners(event);
            return Action.CANCELLED;
        }
        request.body(body);
    }
    if (Utils.webSocketMessage(r))
        return Action.CONTINUE;
    final int interval = extractHeartbeatInterval(impl);
    if (interval != 0) {
        if (!(Utils.pollableTransport(r.transport()) || r.transport() == AtmosphereResource.TRANSPORT.UNDEFINED)) {
            super.inspect(r);
            final boolean wasSuspended = r.isSuspended();
            // Otherwise, the listener will do the job
            if (wasSuspended) {
                clock(interval, r, request, response);
            }
            r.addEventListener(new Clock() {

                @Override
                public void onSuspend(AtmosphereResourceEvent event) {
                    // We did not clocked when this listener was added because connection was not already suspended
                    if (!wasSuspended) {
                        clock(interval, r, request, response);
                    }
                }

                @Override
                public void onResume(AtmosphereResourceEvent event) {
                    cancelF(request);
                }

                @Override
                public void onDisconnect(AtmosphereResourceEvent event) {
                    cancelF(request);
                }

                @Override
                public void onClose(AtmosphereResourceEvent event) {
                    cancelF(request);
                }
            });
        } else {
            return Action.CONTINUE;
        }
        final AsyncIOWriter writer = response.getAsyncIOWriter();
        if (!Utils.resumableTransport(r.transport()) && AtmosphereInterceptorWriter.class.isAssignableFrom(writer.getClass()) && request.getAttribute(INTERCEPTOR_ADDED) == null) {
            AtmosphereInterceptorWriter.class.cast(writer).interceptor(new AsyncIOInterceptorAdapter() {

                @Override
                public byte[] transformPayload(AtmosphereResponse response, byte[] responseDraft, byte[] data) throws IOException {
                    cancelF(request);
                    return responseDraft;
                }

                @Override
                public void postPayload(final AtmosphereResponse response, byte[] data, int offset, int length) {
                    logger.trace("Scheduling heartbeat for {}", r.uuid());
                    clock(interval, r, request, response);
                }
            });
            request.setAttribute(INTERCEPTOR_ADDED, Boolean.TRUE);
        }
    }
    return Action.CONTINUE;
}
Also used : AtmosphereResponse(org.atmosphere.runtime.AtmosphereResponse) AsyncIOWriter(org.atmosphere.runtime.AsyncIOWriter) IOException(java.io.IOException) HeartbeatAtmosphereResourceEvent(org.atmosphere.runtime.HeartbeatAtmosphereResourceEvent) AtmosphereRequest(org.atmosphere.runtime.AtmosphereRequest) AtmosphereResourceEventListenerAdapter(org.atmosphere.runtime.AtmosphereResourceEventListenerAdapter) AtmosphereResourceEvent(org.atmosphere.runtime.AtmosphereResourceEvent) HeartbeatAtmosphereResourceEvent(org.atmosphere.runtime.HeartbeatAtmosphereResourceEvent) AtmosphereInterceptorWriter(org.atmosphere.runtime.AtmosphereInterceptorWriter) AtmosphereResourceImpl(org.atmosphere.runtime.AtmosphereResourceImpl) AsyncIOInterceptorAdapter(org.atmosphere.runtime.AsyncIOInterceptorAdapter)

Aggregations

IOException (java.io.IOException)1 AsyncIOInterceptorAdapter (org.atmosphere.runtime.AsyncIOInterceptorAdapter)1 AsyncIOWriter (org.atmosphere.runtime.AsyncIOWriter)1 AtmosphereInterceptorWriter (org.atmosphere.runtime.AtmosphereInterceptorWriter)1 AtmosphereRequest (org.atmosphere.runtime.AtmosphereRequest)1 AtmosphereResourceEvent (org.atmosphere.runtime.AtmosphereResourceEvent)1 AtmosphereResourceEventListenerAdapter (org.atmosphere.runtime.AtmosphereResourceEventListenerAdapter)1 AtmosphereResourceImpl (org.atmosphere.runtime.AtmosphereResourceImpl)1 AtmosphereResponse (org.atmosphere.runtime.AtmosphereResponse)1 HeartbeatAtmosphereResourceEvent (org.atmosphere.runtime.HeartbeatAtmosphereResourceEvent)1