wAsync (Java)
wAsync — Java Client
Section titled “wAsync — Java Client”A fluent, lightweight WebSocket/HTTP client for the Atmosphere Framework, powered by java.net.http (JDK 21+). Zero external dependencies beyond SLF4J.
Supports WebSocket, Server-Sent Events (SSE), HTTP Streaming, Long-Polling, and gRPC transports with automatic fallback, reconnection, and a type-safe encoder/decoder pipeline.
Maven Coordinates
Section titled “Maven Coordinates”<dependency> <groupId>org.atmosphere</groupId> <artifactId>atmosphere-wasync</artifactId> <version>${project.version}</version></dependency>wAsync ships from the same monorepo as the rest of Atmosphere. Source lives in modules/wasync/.
Quick Start
Section titled “Quick Start”import org.atmosphere.wasync.*;import org.atmosphere.wasync.impl.AtmosphereClient;import org.atmosphere.wasync.impl.AtmosphereRequestBuilder;
var client = AtmosphereClient.newClient();
var request = ((AtmosphereRequestBuilder) client.newRequestBuilder()) .uri("ws://localhost:8080/chat") .transport(Request.TRANSPORT.WEBSOCKET) .build();
var socket = client.create() .on(Event.OPEN, o -> System.out.println("Connected!")) .on(Event.MESSAGE, m -> System.out.println("Received: " + m)) .on(Event.CLOSE, c -> System.out.println("Disconnected")) .on(Event.ERROR, e -> System.err.println("Error: " + e)) .open(request);
socket.fire("Hello from wAsync!");Transports
Section titled “Transports”| Transport | Protocol | Use Case |
|---|---|---|
WEBSOCKET | Full-duplex WebSocket | Real-time bidirectional messaging |
SSE | Server-Sent Events | Server push over HTTP |
STREAMING | HTTP chunked streaming | Continuous server push |
LONG_POLLING | Repeated HTTP requests | Universal fallback |
GRPC | gRPC bidirectional streaming | High-performance binary over HTTP/2 |
Transport Fallback
Section titled “Transport Fallback”Chain transports for automatic fallback:
var request = ((AtmosphereRequestBuilder) client.newRequestBuilder()) .uri("http://localhost:8080/chat") .transport(Request.TRANSPORT.WEBSOCKET) // try first .transport(Request.TRANSPORT.SSE) // fallback .transport(Request.TRANSPORT.LONG_POLLING) // last resort .build();gRPC Transport
Section titled “gRPC Transport”Connect to an Atmosphere gRPC server. Requires atmosphere-grpc, grpc-netty-shaded, grpc-protobuf, and grpc-stub on the classpath.
var request = ((AtmosphereRequestBuilder) client.newRequestBuilder()) .uri("grpc://localhost:9090/chat") .transport(Request.TRANSPORT.GRPC) .build();
var socket = client.create() .on(Event.OPEN, o -> System.out.println("gRPC connected")) .on(Event.MESSAGE, m -> System.out.println("Received: " + m)) .open(request);
socket.fire("Hello via gRPC!");Events
Section titled “Events”socket.on(Event.OPEN, o -> { /* connected */ }) .on(Event.MESSAGE, m -> { /* message received */ }) .on(Event.CLOSE, c -> { /* disconnected */ }) .on(Event.ERROR, e -> { /* error occurred */ }) .on(Event.REOPENED, r -> { /* reconnected after disconnect */ }) .on(Event.STATUS, s -> { /* HTTP status code */ }) .on(Event.HEADERS, h -> { /* response headers */ });Encoders and Decoders
Section titled “Encoders and Decoders”Encoder (client -> server)
Section titled “Encoder (client -> server)”Encoder<ChatMessage, String> jsonEncoder = msg -> new ObjectMapper().writeValueAsString(msg);
var request = ((AtmosphereRequestBuilder) client.newRequestBuilder()) .uri("ws://localhost:8080/chat") .transport(Request.TRANSPORT.WEBSOCKET) .encoder(jsonEncoder) .build();
socket.fire(new ChatMessage("Alice", "Hello!"));Decoder (server -> client)
Section titled “Decoder (server -> client)”Decoder<String, ChatMessage> jsonDecoder = new Decoder<>() { @Override public ChatMessage decode(Event event, String data) { if (event == Event.MESSAGE) { return new ObjectMapper().readValue(data, ChatMessage.class); } return null; }};Connection Options
Section titled “Connection Options”var options = client.newOptionsBuilder() .reconnect(true) .reconnectAttempts(5) .pauseBeforeReconnectInSeconds(3) .waitBeforeUnlocking(2000) .requestTimeoutInSeconds(60) .httpClient(myHttpClient) .build();
var socket = client.create(options) .on(Event.OPEN, o -> System.out.println("Connected")) .open(request);Architecture
Section titled “Architecture”wAsync stacks four layers on top of the JDK’s own HTTP client. Each row below is a horizontal plane in the client; a call to .fire() travels top-down through the codec and transport layers and lands on a JDK socket.
| Layer | Surface | What it does |
|---|---|---|
| Your application | Spring / Quarkus / plain Java | Business code that calls into the Socket API |
| Socket API + codec pipeline | .on(...), .fire(...), .close(); Encoder / Decoder | Outbound: fire(POJO) → encode → send. Inbound: receive → decode → on(MESSAGE). Type-safe, pluggable per transport. |
| Transport layer (auto-fallback) | Request.Builder.transport(...) | WEBSOCKET → SSE → STREAMING → LONG_POLLING → GRPC. Picks the first one the server accepts; falls back automatically on failure. |
| Network backend | java.net.http.HttpClient + grpc-java (optional) | JDK-native HTTP/2 + WebSocket via java.net.http (JDK 21+); bidirectional streaming over HTTP/2 via grpc-java when atmosphere-grpc is on the classpath. |
Samples
Section titled “Samples”- Spring Boot Chat — server with wAsync-compatible endpoint
- gRPC Chat — gRPC transport example
See Also
Section titled “See Also”- Core Runtime — server-side API
- atmosphere.js — TypeScript/browser client
- gRPC Transport
- Module README