use of org.atmosphere.cpr.AtmosphereResource in project flow by vaadin.
the class PushHandler method callWithUi.
/**
* Find the UI for the atmosphere resource, lock it and invoke the callback.
*
* @param resource
* the atmosphere resource for the current request
* @param callback
* the push callback to call when a UI is found and locked
* @param websocket
* true if this is a websocket message (as opposed to a HTTP
* request)
*/
private void callWithUi(final AtmosphereResource resource, final PushEventCallback callback, boolean websocket) {
AtmosphereRequest req = resource.getRequest();
VaadinServletRequest vaadinRequest = new VaadinServletRequest(req, service);
VaadinSession session = null;
if (websocket) {
// For any HTTP request we have already started the request in the
// servlet
service.requestStart(vaadinRequest, null);
}
try {
try {
session = service.findVaadinSession(vaadinRequest);
assert VaadinSession.getCurrent() == session;
} catch (SessionExpiredException e) {
sendNotificationAndDisconnect(resource, VaadinService.createSessionExpiredJSON());
return;
}
UI ui = null;
session.lock();
try {
ui = service.findUI(vaadinRequest);
assert UI.getCurrent() == ui;
if (ui == null) {
sendNotificationAndDisconnect(resource, VaadinService.createUINotFoundJSON());
} else {
callback.run(resource, ui);
}
} catch (final IOException e) {
callErrorHandler(session, e);
} catch (final Exception e) {
SystemMessages msg = service.getSystemMessages(ServletHelper.findLocale(null, vaadinRequest), vaadinRequest);
AtmosphereResource errorResource = resource;
if (ui != null && ui.getInternals().getPushConnection() != null) {
// We MUST use the opened push connection if there is one.
// Otherwise we will write the response to the wrong request
// when using streaming (the client -> server request
// instead of the opened push channel)
errorResource = ((AtmospherePushConnection) ui.getInternals().getPushConnection()).getResource();
}
sendNotificationAndDisconnect(errorResource, VaadinService.createCriticalNotificationJSON(msg.getInternalErrorCaption(), msg.getInternalErrorMessage(), null, msg.getInternalErrorURL()));
callErrorHandler(session, e);
} finally {
try {
session.unlock();
} catch (Exception e) {
getLogger().warn("Error while unlocking session", e);
// can't call ErrorHandler, we (hopefully) don't have a lock
}
}
} finally {
try {
if (websocket) {
service.requestEnd(vaadinRequest, null, session);
}
} catch (Exception e) {
getLogger().warn("Error while ending request", e);
// can't call ErrorHandler, we don't have a lock
}
}
}
use of org.atmosphere.cpr.AtmosphereResource in project flow by vaadin.
the class PushHandler method connectionLost.
void connectionLost(AtmosphereResourceEvent event) {
if (event == null) {
getLogger().error("Could not get event. This should never happen.");
return;
}
// We don't want to use callWithUi here, as it assumes there's a client
// request active and does requestStart and requestEnd among other
// things.
AtmosphereResource resource = event.getResource();
if (resource == null) {
getLogger().error("Could not get resource. This should never happen.");
return;
}
VaadinServletRequest vaadinRequest = new VaadinServletRequest(resource.getRequest(), service);
VaadinSession session;
try {
session = service.findVaadinSession(vaadinRequest);
} catch (SessionExpiredException e) {
// This happens at least if the server is restarted without
// preserving the session. After restart the client reconnects, gets
// a session expired notification and then closes the connection and
// ends up here
getLogger().debug("Session expired before push disconnect event was received", e);
return;
}
UI ui;
session.lock();
try {
VaadinSession.setCurrent(session);
// Sets UI.currentInstance
ui = service.findUI(vaadinRequest);
if (ui == null) {
/*
* UI not found, could be because FF has asynchronously closed
* the websocket connection and Atmosphere has already done
* cleanup of the request attributes.
*
* In that case, we still have a chance of finding the right UI
* by iterating through the UIs in the session looking for one
* using the same AtmosphereResource.
*/
ui = findUiUsingResource(resource, session.getUIs());
if (ui == null) {
getLogger().debug("Could not get UI. This should never happen," + " except when reloading in Firefox and Chrome -" + " see http://dev.vaadin.com/ticket/14251.");
return;
} else {
getLogger().info("No UI was found based on data in the request," + " but a slower lookup based on the AtmosphereResource succeeded." + " See http://dev.vaadin.com/ticket/14251 for more details.");
}
}
PushMode pushMode = ui.getPushConfiguration().getPushMode();
AtmospherePushConnection pushConnection = getConnectionForUI(ui);
String id = resource.uuid();
if (pushConnection == null) {
getLogger().warn("Could not find push connection to close: {} with transport {}", id, resource.transport());
} else {
if (!pushMode.isEnabled()) {
/*
* The client is expected to close the connection after push
* mode has been set to disabled.
*/
getLogger().debug("Connection closed for resource {}", id);
} else {
/*
* Unexpected cancel, e.g. if the user closes the browser
* tab.
*/
getLogger().debug("Connection unexpectedly closed for resource {} with transport {}", id, resource.transport());
}
pushConnection.connectionLost();
}
} catch (final Exception e) {
callErrorHandler(session, e);
} finally {
try {
session.unlock();
} catch (Exception e) {
getLogger().warn("Error while unlocking session", e);
// can't call ErrorHandler, we (hopefully) don't have a lock
}
}
}
use of org.atmosphere.cpr.AtmosphereResource in project atmosphere by Atmosphere.
the class BlockingIOCometSupport method suspend.
/**
* Suspend the connection by blocking the current {@link Thread}
*
* @param action The {@link Action}
* @param req the {@link AtmosphereRequest}
* @param res the {@link AtmosphereResponse}
*/
protected void suspend(Action action, AtmosphereRequest req, AtmosphereResponse res) throws IOException, ServletException {
final CountDownLatch latch = new CountDownLatch(1);
req.setAttribute(LATCH, latch);
boolean ok = true;
AtmosphereResource resource = req.resource();
if (resource != null) {
try {
resource.addEventListener(new OnResume() {
@Override
public void onResume(AtmosphereResourceEvent event) {
latch.countDown();
}
});
if (action.timeout() != -1) {
ok = latch.await(action.timeout(), TimeUnit.MILLISECONDS);
} else {
latch.await();
}
} catch (InterruptedException ex) {
logger.trace("", ex);
} finally {
if (!ok) {
timedout(req, res);
} else {
((AtmosphereResourceImpl) resource).cancel();
}
}
}
}
use of org.atmosphere.cpr.AtmosphereResource in project atmosphere by Atmosphere.
the class SessionBroadcasterCache method retrieveFromCache.
@Override
public List<Object> retrieveFromCache(String broadcasterId, String uuid) {
if (uuid == null) {
throw new IllegalArgumentException("AtmosphereResource can't be null");
}
List<Object> result = new ArrayList<>();
try {
AtmosphereResource r = config.resourcesFactory().find(uuid);
if (r == null) {
logger.trace("Invalid UUID {}", uuid);
return result;
}
HttpSession session = r.session();
if (session == null) {
logger.error(ERROR_MESSAGE);
return result;
}
String cacheHeaderTimeStr = (String) session.getAttribute(broadcasterId);
if (cacheHeaderTimeStr == null)
return result;
long cacheHeaderTime = Long.parseLong(cacheHeaderTimeStr);
return get(cacheHeaderTime);
} catch (IllegalStateException ex) {
logger.trace("", ex);
logger.warn("The Session has been invalidated. Unable to retrieve cached messages");
return Collections.emptyList();
}
}
use of org.atmosphere.cpr.AtmosphereResource in project atmosphere by Atmosphere.
the class AtmosphereServiceProcessor method handle.
@Override
public void handle(AtmosphereFramework framework, Class<Object> annotatedClass) {
try {
AtmosphereService a = annotatedClass.getAnnotation(AtmosphereService.class);
framework.setBroadcasterCacheClassName(a.broadcasterCache().getName());
atmosphereConfig(a.atmosphereConfig(), framework);
framework.setDefaultBroadcasterClassName(a.broadcaster().getName());
filters(a.broadcastFilters(), framework);
LinkedList<AtmosphereInterceptor> l = new LinkedList<>();
AtmosphereInterceptor aa = listeners(a.listeners(), framework);
if (aa != null) {
l.add(aa);
}
if (!a.servlet().isEmpty()) {
final ReflectorServletProcessor r = framework.newClassInstance(ReflectorServletProcessor.class, ReflectorServletProcessor.class);
r.setServletClassName(a.servlet());
String mapping = a.path();
AnnotationUtil.interceptorsForHandler(framework, Arrays.asList(a.interceptors()), l);
if (!a.dispatch()) {
AtmosphereHandler proxy = new AtmosphereServletProcessor() {
private String method = "GET";
@Override
public void onRequest(AtmosphereResource resource) throws IOException {
if (!resource.getRequest().getMethod().equalsIgnoreCase(method)) {
r.onRequest(resource);
}
}
@Override
public void onStateChange(AtmosphereResourceEvent event) throws IOException {
r.onStateChange(event);
}
@Override
public void destroy() {
r.destroy();
}
@Override
public void init(AtmosphereConfig config) throws ServletException {
String s = config.getInitParameter(ATMOSPHERERESOURCE_INTERCEPTOR_METHOD);
if (s != null) {
method = s;
}
r.init(config);
}
};
framework.addAtmosphereHandler(mapping, proxy, l);
} else {
framework.addAtmosphereHandler(mapping, r, l);
}
} else {
interceptors(a.interceptors(), framework);
}
} catch (Throwable e) {
logger.warn("", e);
}
}
Aggregations