Search in sources :

Example 1 with AtmosphereResourceImpl

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

the class OnMessage method onStateChange.

@Override
public final void onStateChange(AtmosphereResourceEvent event) throws IOException {
    AtmosphereResponse response = ((AtmosphereResourceImpl) event.getResource()).getResponse(false);
    logger.trace("{} with event {}", event.getResource().uuid(), event);
    if (event.isCancelled() || event.isClosedByApplication() || event.isClosedByClient()) {
        onDisconnect(response);
    } else if (event.getMessage() != null && List.class.isAssignableFrom(event.getMessage().getClass())) {
        List<T> messages = List.class.cast(event.getMessage());
        for (T t : messages) {
            onMessage(response, t);
        }
    } else if (event.isResuming()) {
        onResume(response);
    } else if (event.isResumedOnTimeout()) {
        onTimeout(response);
    } else if (event.isSuspended()) {
        onMessage(response, (T) event.getMessage());
    }
    postStateChange(event);
}
Also used : AtmosphereResponse(org.atmosphere.runtime.AtmosphereResponse) List(java.util.List) AtmosphereResourceImpl(org.atmosphere.runtime.AtmosphereResourceImpl)

Example 2 with AtmosphereResourceImpl

use of org.atmosphere.runtime.AtmosphereResourceImpl 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)

Example 3 with AtmosphereResourceImpl

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

the class DefaultWebSocketProcessor method close.

@Override
public void close(final WebSocket webSocket, int closeCode) {
    WebSocketHandler webSocketHandler = webSocket.webSocketHandler();
    // A message might be in the process of being processed and the websocket gets closed. In that corner
    // case the webSocket.resource will be set to false and that might cause NPE in some WebSocketProcol implementation
    // We could potentially synchronize on webSocket but since it is a rare case, it is better to not synchronize.
    // synchronized (webSocket) {
    final AtmosphereResourceImpl resource = (AtmosphereResourceImpl) webSocket.resource();
    if (resource == null) {
        logger.trace("Already closed {}", webSocket);
    } else {
        final boolean allowedToClose = allowedCloseCode(closeCode);
        final AtmosphereRequest r = resource.getRequest(false);
        final AtmosphereResponse s = resource.getResponse(false);
        boolean ff = r.getAttribute("firefox") != null;
        boolean completeLifecycle = true;
        try {
            webSocketProtocol.onClose(webSocket);
            if (webSocketHandler != null) {
                webSocketHandler.onClose(webSocket);
            }
            logger.trace("About to close AtmosphereResource for {} with code {}", resource, closeCode);
            if (!resource.getAtmosphereResourceEvent().isClosedByClient() && !resource.getAtmosphereResourceEvent().isClosedByApplication() && !resource.isCancelled()) {
                // Better to call onDisconnect that onResume.
                if (allowedToClose) {
                    if (ff || closingTime > 0) {
                        completeLifecycle = false;
                        logger.debug("Delaying closing operation for firefox and resource {}", resource.uuid());
                        ExecutorsFactory.getScheduler(framework.getAtmosphereConfig()).schedule(new Callable<Object>() {

                            @Override
                            public Object call() throws Exception {
                                executeClose(webSocket, 1005);
                                finish(webSocket, resource, r, s, !allowedToClose);
                                return null;
                            }
                        }, ff ? (closingTime == 0 ? 1000 : closingTime) : closingTime, TimeUnit.MILLISECONDS);
                        resource.getAndSetPendingClose();
                    } else {
                        executeClose(webSocket, closeCode);
                    }
                } else {
                    logger.debug("Timeout {}", resource.uuid());
                    asynchronousProcessor.endRequest(AtmosphereResourceImpl.class.cast(webSocket.resource()), false);
                }
            } else {
                logger.trace("Unable to properly complete {}", resource == null ? "null" : resource.uuid());
                completeLifecycle = false;
            }
        } finally {
            if (completeLifecycle) {
                finish(webSocket, resource, r, s, !allowedToClose);
            }
        }
    }
}
Also used : AtmosphereResponse(org.atmosphere.runtime.AtmosphereResponse) AtmosphereRequest(org.atmosphere.runtime.AtmosphereRequest) AtmosphereResourceImpl(org.atmosphere.runtime.AtmosphereResourceImpl) ServletException(javax.servlet.ServletException) AtmosphereMappingException(org.atmosphere.runtime.AtmosphereMappingException) IOException(java.io.IOException)

Example 4 with AtmosphereResourceImpl

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

the class DefaultWebSocketProcessor method open.

@Override
public final void open(final WebSocket webSocket, final AtmosphereRequest request, final AtmosphereResponse response) throws IOException {
    if (framework.isDestroyed())
        return;
    // TODO: Fix this. Instead add an Interceptor.
    if (framework.getAtmosphereConfig().handlers().isEmpty()) {
        synchronized (framework) {
            if (handlers.isEmpty()) {
                logger.warn("No AtmosphereHandler or WebSocketHandler installed. Adding a default one.");
            }
            framework.addAtmosphereHandler(ROOT_MASTER, REFLECTOR_ATMOSPHEREHANDLER);
        }
    }
    request.headers(configureHeader(request)).setAttribute(WebSocket.WEBSOCKET_SUSPEND, true);
    AtmosphereResource r = framework.atmosphereFactory().create(framework.getAtmosphereConfig(), response, framework.getAsyncSupport());
    boolean cleanUpAfterDisconnect = false;
    try {
        request.setAttribute(INJECTED_ATMOSPHERE_RESOURCE, r);
        request.setAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID, r.uuid());
        if (Utils.firefoxWebSocketEnabled(request)) {
            request.setAttribute("firefox", "true");
        }
        AtmosphereResourceImpl.class.cast(r).webSocket(webSocket);
        webSocket.resource(r);
        webSocketProtocol.onOpen(webSocket);
        WebSocketHandler proxy = null;
        if (!handlers.isEmpty()) {
            WebSocketHandlerProxy handler = mapper.map(request, handlers);
            if (handler == null) {
                logger.debug("No WebSocketHandler maps request for {} with mapping {}", request.getRequestURI(), handlers);
                throw new AtmosphereMappingException("No AtmosphereHandler maps request for " + request.getRequestURI());
            }
            proxy = postProcessMapping(webSocket, request, handler);
        }
        dispatch(webSocket, request, response);
        if (proxy != null) {
            webSocket.webSocketHandler(proxy).resource().suspend(-1);
            proxy.onOpen(webSocket);
        }
        request.removeAttribute(INJECTED_ATMOSPHERE_RESOURCE);
        // Resource can be null if the client disconnect.
        if (webSocket.resource() != null) {
            final Action action = ((AtmosphereResourceImpl) webSocket.resource()).action();
            if (action.timeout() != -1 && !framework.getAsyncSupport().getContainerName().contains("Netty")) {
                final AtomicReference<Future<?>> f = new AtomicReference();
                f.set(scheduler.scheduleAtFixedRate(new Runnable() {

                    @Override
                    public void run() {
                        if (WebSocket.class.isAssignableFrom(webSocket.getClass()) && System.currentTimeMillis() - WebSocket.class.cast(webSocket).lastWriteTimeStampInMilliseconds() > action.timeout()) {
                            asynchronousProcessor.endRequest(((AtmosphereResourceImpl) webSocket.resource()), false);
                            f.get().cancel(true);
                        }
                    }
                }, action.timeout(), action.timeout(), TimeUnit.MILLISECONDS));
            }
        } else {
            logger.warn("AtmosphereResource was null");
            cleanUpAfterDisconnect = true;
        }
        notifyListener(webSocket, new WebSocketEventListener.WebSocketEvent("", CONNECT, webSocket));
    } catch (AtmosphereMappingException ex) {
        cleanUpAfterDisconnect = true;
        throw ex;
    } catch (IOException ex) {
        cleanUpAfterDisconnect = true;
        throw ex;
    } catch (Exception ex) {
        logger.trace("onOpen exception", ex);
        cleanUpAfterDisconnect = true;
    } finally {
        if (cleanUpAfterDisconnect) {
            logger.warn("Problem opening websocket for {}", r.uuid());
            framework.atmosphereFactory().remove(r.uuid());
            AtmosphereResourceEventImpl.class.cast(r.getAtmosphereResourceEvent()).setCancelled(true);
            AsynchronousProcessor.class.cast(framework.getAsyncSupport()).completeLifecycle(r, true);
        }
        webSocket.shiftAttributes();
    }
}
Also used : Action(org.atmosphere.runtime.Action) AtmosphereResource(org.atmosphere.runtime.AtmosphereResource) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) AtmosphereResourceEventImpl(org.atmosphere.runtime.AtmosphereResourceEventImpl) WebSocketEvent(org.atmosphere.websocket.WebSocketEventListener.WebSocketEvent) ServletException(javax.servlet.ServletException) AtmosphereMappingException(org.atmosphere.runtime.AtmosphereMappingException) IOException(java.io.IOException) AsynchronousProcessor(org.atmosphere.runtime.AsynchronousProcessor) AtmosphereMappingException(org.atmosphere.runtime.AtmosphereMappingException) Future(java.util.concurrent.Future) AtmosphereResourceImpl(org.atmosphere.runtime.AtmosphereResourceImpl)

Example 5 with AtmosphereResourceImpl

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

the class DefaultWebSocketProcessor method notifyListener.

@Override
public void notifyListener(WebSocket webSocket, WebSocketEventListener.WebSocketEvent event) {
    AtmosphereResource resource = webSocket.resource();
    if (resource == null)
        return;
    AtmosphereResourceImpl r = AtmosphereResourceImpl.class.cast(resource);
    for (AtmosphereResourceEventListener l : r.atmosphereResourceEventListener()) {
        if (WebSocketEventListener.class.isAssignableFrom(l.getClass())) {
            try {
                switch(event.type()) {
                    case CONNECT:
                        WebSocketEventListener.class.cast(l).onConnect(event);
                        break;
                    case DISCONNECT:
                        WebSocketEventListener.class.cast(l).onDisconnect(event);
                        onDisconnect(event, l);
                        break;
                    case CONTROL:
                        WebSocketEventListener.class.cast(l).onControl(event);
                        break;
                    case MESSAGE:
                        WebSocketEventListener.class.cast(l).onMessage(event);
                        break;
                    case HANDSHAKE:
                        WebSocketEventListener.class.cast(l).onHandshake(event);
                        break;
                    case CLOSE:
                        boolean isClosedByClient = r.getAtmosphereResourceEvent().isClosedByClient();
                        l.onDisconnect(new AtmosphereResourceEventImpl(r, !isClosedByClient, false, isClosedByClient, null));
                        onDisconnect(event, l);
                        WebSocketEventListener.class.cast(l).onClose(event);
                        break;
                }
            } catch (Throwable t) {
                logger.debug("Listener error {}", t);
                try {
                    WebSocketEventListener.class.cast(l).onThrowable(new AtmosphereResourceEventImpl(r, false, false, t));
                } catch (Throwable t2) {
                    logger.warn("Listener error {}", t2);
                }
            }
        } else {
            switch(event.type()) {
                case CLOSE:
                    boolean isClosedByClient = r.getAtmosphereResourceEvent().isClosedByClient();
                    l.onDisconnect(new AtmosphereResourceEventImpl(r, !isClosedByClient, false, isClosedByClient, null));
                    break;
            }
        }
    }
}
Also used : AtmosphereResourceEventListener(org.atmosphere.runtime.AtmosphereResourceEventListener) AtmosphereResource(org.atmosphere.runtime.AtmosphereResource) AtmosphereResourceImpl(org.atmosphere.runtime.AtmosphereResourceImpl) AtmosphereResourceEventImpl(org.atmosphere.runtime.AtmosphereResourceEventImpl)

Aggregations

AtmosphereResourceImpl (org.atmosphere.runtime.AtmosphereResourceImpl)21 AtmosphereRequest (org.atmosphere.runtime.AtmosphereRequest)15 IOException (java.io.IOException)13 AtmosphereResponse (org.atmosphere.runtime.AtmosphereResponse)11 ServletException (javax.servlet.ServletException)8 AsynchronousProcessor (org.atmosphere.runtime.AsynchronousProcessor)7 AtmosphereFramework (org.atmosphere.runtime.AtmosphereFramework)7 BeforeMethod (org.testng.annotations.BeforeMethod)6 SimpleBroadcaster (org.atmosphere.util.SimpleBroadcaster)5 ArrayList (java.util.ArrayList)4 Enumeration (java.util.Enumeration)4 ServletConfig (javax.servlet.ServletConfig)4 ServletContext (javax.servlet.ServletContext)4 Action (org.atmosphere.runtime.Action)3 AtmosphereResource (org.atmosphere.runtime.AtmosphereResource)3 AtmosphereResourceEvent (org.atmosphere.runtime.AtmosphereResourceEvent)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 AtmosphereInterceptor (org.atmosphere.runtime.AtmosphereInterceptor)2 AtmosphereMappingException (org.atmosphere.runtime.AtmosphereMappingException)2 AtmosphereResourceEventImpl (org.atmosphere.runtime.AtmosphereResourceEventImpl)2