-
-
Notifications
You must be signed in to change notification settings - Fork 755
Getting Started with atmosphere.js
jfarcand edited this page Feb 18, 2026
·
1 revision
atmosphere.js is a TypeScript client library for connecting to Atmosphere endpoints. It supports WebSocket, SSE, long-polling, and streaming with automatic transport fallback.
npm install atmosphere.jsOr include directly via <script> tag (the library exposes a global atmosphere object):
<script src="atmosphere.js"></script>import { Atmosphere } from 'atmosphere.js';
const atm = new Atmosphere();
const subscription = await atm.subscribe(
{
url: 'http://localhost:8080/atmosphere/chat',
transport: 'websocket',
fallbackTransport: 'long-polling',
trackMessageLength: true,
contentType: 'application/json',
},
{
open: (response) => {
console.log('Connected via', response.transport);
},
message: (response) => {
const data = JSON.parse(response.responseBody);
console.log('Received:', data);
},
close: () => console.log('Disconnected'),
error: (error) => console.error('Error:', error),
}
);
// Send a message
subscription.push(JSON.stringify({ author: 'Alice', message: 'Hello!' }));
// Close the connection
await subscription.close();<script src="atmosphere.js"></script>
<script>
(async function() {
const subscription = await atmosphere.atmosphere.subscribe(
{
url: '/atmosphere/chat',
transport: 'websocket',
fallbackTransport: 'long-polling',
trackMessageLength: true,
contentType: 'application/json'
},
{
open: (response) => console.log('Connected:', response.transport),
message: (response) => {
const msg = JSON.parse(response.responseBody);
console.log(msg.author + ':', msg.message);
}
}
);
subscription.push(JSON.stringify({ author: 'Alice', message: 'Hello!' }));
})();
</script>| Transport | Description | Bidirectional |
|---|---|---|
websocket |
Full-duplex WebSocket (default, recommended) | ✅ |
sse |
Server-Sent Events (server→client) + XHR POST (client→server) | ✅ |
streaming |
Long-lived XHR with incremental reads | ✅ |
long-polling |
XHR open/close cycle per response | ✅ |
The client tries transport first. If it fails, it automatically falls back to fallbackTransport and notifies via the transportFailure handler.
{
url: string; // Atmosphere endpoint URL
transport: TransportType; // 'websocket' | 'sse' | 'long-polling' | 'streaming'
fallbackTransport?: TransportType;
contentType?: string; // Default: 'text/plain'
trackMessageLength?: boolean; // Length-delimited messages (recommended)
messageDelimiter?: string; // Default: '|'
enableProtocol?: boolean; // Atmosphere protocol handshake
timeout?: number; // Inactivity timeout (ms)
connectTimeout?: number; // Connection timeout (ms)
reconnect?: boolean; // Auto-reconnect on disconnect
reconnectInterval?: number; // Base reconnect delay (ms)
maxReconnectOnClose?: number; // Max reconnect attempts (default: 5)
headers?: Record<string, string>;
withCredentials?: boolean; // Include cookies in cross-origin requests
heartbeat?: {
client?: number; // Client heartbeat interval (ms)
server?: number; // Expected server heartbeat interval (ms)
};
}{
open?: (response) => void; // Connection established
message?: (response) => void; // Data received
close?: (response) => void; // Connection closed
error?: (error) => void; // Error occurred
reopen?: (response) => void; // Reconnected after disconnect
reconnect?: (request, response) => void; // Attempting reconnect
transportFailure?: (reason, request) => void; // Primary transport failed
clientTimeout?: (request) => void; // Inactivity timeout
failureToReconnect?: (request, response) => void; // All retries exhausted
}The subscribe() call returns a Subscription object:
subscription.push(message); // Send string, object, or ArrayBuffer
await subscription.close(); // Disconnect
subscription.suspend(); // Pause receiving
await subscription.resume(); // Resume receiving
subscription.state; // 'connected' | 'disconnected' | 'reconnecting' | ...
subscription.id; // Unique subscription IDatmosphere.js includes a high-level Rooms API for presence-aware group messaging:
import { Atmosphere, AtmosphereRooms } from 'atmosphere.js';
const atmosphere = new Atmosphere();
const rooms = new AtmosphereRooms(atmosphere, {
url: '/atmosphere/chat',
transport: 'websocket',
});
const lobby = await rooms.join('lobby', { id: 'alice' }, {
message: (data, member) => console.log(`${member.id}: ${data}`),
join: (event) => console.log(`${event.member.id} joined`),
leave: (event) => console.log(`${event.member.id} left`),
});
lobby.broadcast('Hello!');
lobby.sendTo('bob', 'Direct message');
lobby.members; // Map of member ID → RoomMember
lobby.leave();
// Leave all rooms and close connection
await rooms.leaveAll();See Understanding Rooms for the full server + client room API.
import { useRoom } from 'atmosphere.js/react';
function Chat() {
const { members, messages, broadcast } = useRoom<ChatMessage>({
request: { url: '/atmosphere/chat', transport: 'websocket' },
room: 'lobby',
member: { id: 'alice' },
});
return <button onClick={() => broadcast({ text: 'Hi!' })}>Send</button>;
}Requires an <AtmosphereProvider> ancestor.
<script setup>
import { useRoom } from 'atmosphere.js/vue';
const { members, messages, broadcast } = useRoom(
{ url: '/atmosphere/chat', transport: 'websocket' },
'lobby', { id: 'alice' }
);
</script><script>
import { createRoomStore } from 'atmosphere.js/svelte';
const { store: lobby, broadcast } = createRoomStore(
{ url: '/atmosphere/chat', transport: 'websocket' },
'lobby', { id: 'alice' }
);
</script>const atmosphere = new Atmosphere({
logLevel: 'debug', // 'debug' | 'info' | 'warn' | 'error' | 'silent'
defaultTransport: 'websocket',
fallbackTransport: 'long-polling',
});Transform messages before sending or after receiving:
const atmosphere = new Atmosphere({
interceptors: [{
name: 'json-wrapper',
onOutgoing: (data) => JSON.stringify({ payload: data }),
onIncoming: (body) => JSON.parse(body).payload,
}],
});