-
-
Notifications
You must be signed in to change notification settings - Fork 761
Getting Started with atmosphere.js
jfarcand edited this page Feb 18, 2026
·
2 revisions
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.js
Or 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 ID
atmosphere.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, }], });