Skip to content

Navigation Menu

Sign in
Sign up

Understanding ManagedService

jfarcand edited this page Feb 18, 2026 · 3 revisions

Understanding @ManagedService

@ManagedService is the recommended way to build Atmosphere applications. It provides an annotation-driven programming model with automatic lifecycle management, message encoding/decoding, and dependency injection.

Quick Example

@ManagedService(path = "/chat")
public class Chat {
 @Inject
 private BroadcasterFactory factory;
 @Inject
 private AtmosphereResource r;
 @Inject
 private AtmosphereResourceEvent event;
 @Ready
 public void onReady() {
 // Connection is suspended and ready to receive messages
 }
 @Disconnect
 public void onDisconnect() {
 if (event.isCancelled()) {
 // Unexpected disconnect
 } else if (event.isClosedByClient()) {
 // Client closed the connection
 }
 }
 @Message(encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class})
 public Message onMessage(Message message) {
 // Return value is broadcast to all connected clients
 return message;
 }
 @Heartbeat
 public void onHeartbeat(AtmosphereResourceEvent event) {
 // Client heartbeat received
 }
}

What @ManagedService Configures Automatically

When you annotate a class with @ManagedService, Atmosphere automatically installs:

Component Purpose
UUIDBroadcasterCache Caches messages so reconnecting clients don't miss data
AtmosphereResourceLifecycleInterceptor Manages connection suspend/resume lifecycle
TrackMessageSizeInterceptor Guarantees complete message delivery
HeartbeatInterceptor Keeps connections alive across proxies
SuspendTrackerInterceptor Tracks suspended connections

Annotation Reference

@ManagedService (class-level)

Attribute Type Default Description
path String "/" URL mapping for this handler
broadcaster Class DefaultBroadcaster.class Broadcaster implementation
broadcasterCache Class UUIDBroadcasterCache.class Message cache implementation
interceptors Class[] {} Additional interceptors (appended to defaults)
broadcastFilters Class[] {} Message filters applied before broadcast
listeners Class[] {} Event listeners for connection tracking
atmosphereConfig String[] {} Key-value config (e.g. "org.atmosphere.cpr.maxInactiveActivity=120000")

Lifecycle Annotations (method-level)

Annotation When Invoked Typical Use
@Ready Connection suspended and ready Log connection, send welcome message
@Disconnect Client disconnects Clean up, notify others
@Message Message received from Broadcaster Process and optionally re-broadcast
@Heartbeat Client heartbeat received Logging, presence tracking

HTTP Method Annotations (method-level)

Annotation Description
@Get Handle HTTP GET (e.g. set response encoding)
@Post Handle HTTP POST
@Put Handle HTTP PUT
@Delete Handle HTTP DELETE

Utility Annotations

Annotation Target Description
@Singleton Class Single instance shared across all connections
@PathParam Field Bind URI template variable (e.g. /chat/{room})
@DeliverTo Method Control broadcast scope: RESOURCE, BROADCASTER, or ALL

Dependency Injection

@ManagedService classes support @Inject (Jakarta CDI) for:

@Inject private AtmosphereResource r; // Current connection
@Inject private AtmosphereResourceEvent event; // Current event
@Inject private BroadcasterFactory factory; // Create/lookup broadcasters
@Inject @Named("/chat") private Broadcaster b; // Named broadcaster

Encoders and Decoders

The @Message annotation supports automatic type conversion:

// Encoder: converts your object to a String for the wire
public class JacksonEncoder implements Encoder<Message, String> {
 @Inject private ObjectMapper mapper;
 @Override
 public String encode(Message m) {
 return mapper.writeValueAsString(m);
 }
}
// Decoder: converts incoming String to your object
public class JacksonDecoder implements Decoder<String, Message> {
 @Inject private ObjectMapper mapper;
 @Override
 public Message decode(String s) {
 return mapper.readValue(s, Message.class);
 }
}
// Usage
@Message(encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class})
public Message onMessage(Message message) {
 return message; // Automatically decoded from JSON, re-encoded for broadcast
}

Path Templates

Use @PathParam to capture URI variables:

@ManagedService(path = "/chat/{room}")
public class Chat {
 @PathParam("room")
 private String roomName;
 @Ready
 public void onReady() {
 // roomName is populated from the URL
 // e.g. /chat/lobby → roomName = "lobby"
 }
}

Each unique path creates a separate Broadcaster, so /chat/lobby and /chat/general have independent message streams.

Delivery Scope

Control who receives the return value of a @Message method:

@Message
@DeliverTo(DeliverTo.DELIVER_TO.BROADCASTER) // All connections on this path
public String onMessage(String message) {
 return "Echo: " + message;
}
@Message
@DeliverTo(DeliverTo.DELIVER_TO.RESOURCE) // Only the sender
public String onPrivateMessage(String message) {
 return "Only you see this";
}

Configuration

Pass Atmosphere config via the atmosphereConfig attribute:

@ManagedService(
 path = "/chat",
 atmosphereConfig = {
 "org.atmosphere.cpr.maxInactiveActivity=120000",
 "org.atmosphere.websocket.maxTextMessageSize=65536"
 }
)

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /