Skip to content

Understanding AtmosphereInterceptor

jfarcand edited this page Feb 18, 2026 · 18 revisions

Understanding AtmosphereInterceptor

Advanced topic. Interceptors let you customize the request/response pipeline. Most applications don't need custom interceptors — @ManagedService installs the necessary ones automatically.

An AtmosphereInterceptor sits in the processing chain between the client and your handler. It can inspect, modify, or reject requests and responses.

Built-in Interceptors

These are installed automatically by @ManagedService:

Interceptor Purpose
AtmosphereResourceLifecycleInterceptor Auto-suspends connections based on transport
TrackMessageSizeInterceptor Prepends message length for guaranteed delivery
HeartbeatInterceptor Sends periodic heartbeats to keep connections alive
SuspendTrackerInterceptor Tracks suspended resources for cleanup
ManagedServiceInterceptor Routes messages to @Message annotated methods

Other useful interceptors:

Interceptor Purpose
RoomProtocolInterceptor Bridges atmosphere.js room protocol to server-side Rooms
RoomInterceptor Auto-joins resources to rooms based on URL path
BroadcastOnPostAtmosphereInterceptor Auto-broadcasts POST body to the Broadcaster
CorsInterceptor Adds CORS headers

Writing a Custom Interceptor

public class LoggingInterceptor extends AtmosphereInterceptorAdapter {

    @Override
    public Action inspect(AtmosphereResource r) {
        // Called before the handler
        log.info("Request from {} via {}", r.uuid(), r.transport());

        return Action.CONTINUE;    // Proceed to next interceptor/handler
        // return Action.CANCELLED; // Stop processing (e.g., reject request)
        // return Action.SUSPEND;   // Suspend the connection
    }

    @Override
    public void postInspect(AtmosphereResource r) {
        // Called after the handler
    }

    @Override
    public void configure(AtmosphereConfig config) {
        // Called once at startup
    }
}

Registering Interceptors

Via @ManagedService

@ManagedService(path = "/chat",
    interceptors = {LoggingInterceptor.class, RateLimitInterceptor.class})
public class Chat { /* ... */ }

These are appended to the default set — they don't replace it.

Via Annotation

@AtmosphereInterceptorService
public class LoggingInterceptor extends AtmosphereInterceptorAdapter {
    // Auto-registered when annotation scanning is enabled
}

Programmatically

framework.interceptor(new LoggingInterceptor());

Interceptor Priority

Control execution order with PRIORITY:

public class EarlyInterceptor extends AtmosphereInterceptorAdapter {
    @Override
    public PRIORITY priority() {
        return InvokationOrder.BEFORE_DEFAULT;  // Run before defaults
        // InvokationOrder.AFTER_DEFAULT       // Run after defaults (default)
        // InvokationOrder.FIRST_BEFORE_DEFAULT // Run first, before everything
    }
}

Clone this wiki locally