use of org.atmosphere.runtime.AtmosphereResource in project atmosphere by Atmosphere.
the class IdleResourceInterceptor method idleResources.
protected void idleResources() {
if (logger.isTraceEnabled()) {
logger.trace("{} monitoring {} AtmosphereResources", getClass().getSimpleName(), config.resourcesFactory().findAll().size());
}
for (AtmosphereResource r : config.resourcesFactory().findAll()) {
if (Utils.pollableTransport(r.transport())) {
continue;
}
AtmosphereRequest req = AtmosphereResourceImpl.class.cast(r).getRequest(false);
try {
if (req.getAttribute(MAX_INACTIVE) == null) {
logger.warn("Invalid state {}", r);
r.removeFromAllBroadcasters();
config.resourcesFactory().unRegisterUuidForFindCandidate(r);
continue;
}
long l = (Long) req.getAttribute(MAX_INACTIVE);
if (logger.isTraceEnabled() && l > 0) {
logger.trace("Expiring {} in {}", r.uuid(), System.currentTimeMillis() - l);
}
if (l > 0 && System.currentTimeMillis() - l > maxInactiveTime) {
try {
req.setAttribute(MAX_INACTIVE, (long) -1);
logger.debug("IdleResourceInterceptor disconnecting {}", r);
Future<?> f = (Future<?>) req.getAttribute(HeartbeatInterceptor.HEARTBEAT_FUTURE);
if (f != null)
f.cancel(false);
req.removeAttribute(HeartbeatInterceptor.HEARTBEAT_FUTURE);
WebSocket webSocket = AtmosphereResourceImpl.class.cast(r).webSocket();
if (webSocket != null) {
webSocket.close();
} else {
AsynchronousProcessor.class.cast(config.framework().getAsyncSupport()).endRequest(AtmosphereResourceImpl.class.cast(r), true);
}
} finally {
r.removeFromAllBroadcasters();
config.resourcesFactory().unRegisterUuidForFindCandidate(r);
}
}
} catch (Throwable e) {
logger.warn("IdleResourceInterceptor", e);
}
}
}
use of org.atmosphere.runtime.AtmosphereResource in project atmosphere by Atmosphere.
the class DefaultWebSocketProcessor method handleException.
private void handleException(Exception ex, WebSocket webSocket, WebSocketHandler webSocketHandler) {
logger.error("", ex);
AtmosphereResource r = webSocket.resource();
if (r != null) {
webSocketHandler.onError(webSocket, new WebSocketException(ex, new AtmosphereResponseImpl.Builder().request(r != null ? AtmosphereResourceImpl.class.cast(r).getRequest(false) : null).status(500).statusMessage("Server Error").build()));
}
}
use of org.atmosphere.runtime.AtmosphereResource in project atmosphere by Atmosphere.
the class DefaultWebSocketProcessor method executeClose.
public void executeClose(WebSocket webSocket, int closeCode) {
AtmosphereResource r = webSocket.resource();
boolean isClosedByClient = r == null ? true : r.getAtmosphereResourceEvent().isClosedByClient();
try {
if (r != null) {
asynchronousProcessor.endRequest(AtmosphereResourceImpl.class.cast(r), true);
}
} finally {
if (!isClosedByClient) {
notifyListener(webSocket, new WebSocketEventListener.WebSocketEvent(closeCode, CLOSE, webSocket));
}
}
}
use of org.atmosphere.runtime.AtmosphereResource 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();
}
}
use of org.atmosphere.runtime.AtmosphereResource 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;
}
}
}
}
Aggregations