-
-
Notifications
You must be signed in to change notification settings - Fork 755
Durable Sessions
WebSocket sessions are ephemeral — when the server restarts, all connections are lost and clients must reconnect from scratch, losing their room memberships, broadcaster subscriptions, and application metadata. Durable Sessions solve this by persisting session state to a backing store (SQLite or Redis) so that reconnecting clients automatically resume exactly where they left off.
┌──────────────┐ X-Atmosphere-Session-Token ┌──────────────────────┐
│ atmosphere.js│ ──────────────────────────────────→ │ DurableSession │
│ client │ ←────────────────────────────────── │ Interceptor │
└──────────────┘ token assigned on first connect │ │
│ save / restore │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ SessionStore SPI │
├──────────────────────┤
│ InMemorySessionStore │ (dev/test)
│ SqliteSessionStore │ (single-node)
│ RedisSessionStore │ (clustered)
└──────────────────────┘
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-spring-boot-starter</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-durable-sessions</artifactId>
<version>4.0.1</version>
</dependency>
<!-- Pick one: -->
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-durable-sessions-sqlite</artifactId>
<version>4.0.1</version>
</dependency>atmosphere.durable-sessions.enabled=true
atmosphere.durable-sessions.session-ttl-minutes=1440
atmosphere.durable-sessions.cleanup-interval-seconds=60@Bean
public SessionStore sessionStore() {
return new SqliteSessionStore(Path.of("data/sessions.db"));
}If no SessionStore bean is defined, an InMemorySessionStore is used
automatically (useful for development, but sessions won't survive restarts).
import { atmosphere } from 'atmosphere.js';
const atmosphere = new Atmosphere();
const sub = await atmosphere.subscribe({
url: '/atmosphere/chat',
transport: 'websocket',
sessionToken: localStorage.getItem('atmo-session-token'),
});The sessionToken is sent as X-Atmosphere-Session-Token on every request.
The SessionStore interface defines six methods:
| Method | Description |
|---|---|
save(session) |
Persist a session (upsert) |
restore(token) |
Look up a session by token |
remove(token) |
Delete a session |
touch(token) |
Update the last-seen timestamp |
removeExpired(ttl) |
Find and remove sessions older than TTL |
close() |
Release resources |
public record DurableSession(
String token, // unique session token
String resourceId, // AtmosphereResource UUID
Set<String> rooms, // room names
Set<String> broadcasters, // broadcaster IDs
Map<String, String> metadata, // app-defined key-value pairs
Instant createdAt,
Instant lastSeen
) { }Zero-configuration, embedded database. Perfect for single-node deployments, development, and edge/IoT scenarios.
// Default: atmosphere-sessions.db in working directory
var store = new SqliteSessionStore();
// Custom path
var store = new SqliteSessionStore(Path.of("/data/sessions.db"));
// In-memory (for testing)
var store = SqliteSessionStore.inMemory();Maven:
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-durable-sessions-sqlite</artifactId>
<version>4.0.1</version>
</dependency>Sessions shared across all nodes via Redis. Ideal for multi-node production deployments and Kubernetes environments.
// Basic connection
var store = new RedisSessionStore("redis://localhost:6379");
// With custom TTL
var store = new RedisSessionStore("redis://localhost:6379", Duration.ofHours(12));
// Share connection with atmosphere-redis clustering
var store = new RedisSessionStore(existingLettuceConnection, Duration.ofHours(24));Maven:
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-durable-sessions-redis</artifactId>
<version>4.0.1</version>
</dependency>-
First connection —
DurableSessionInterceptor.inspect()creates a newDurableSessionwith a UUID token, saves it to the store, and sends the token back viaX-Atmosphere-Session-Tokenresponse header. -
Disconnect — A listener captures the client's current rooms and broadcaster subscriptions and saves them to the store.
-
Reconnection — The client sends its token. The interceptor restores the session, re-subscribes to all broadcasters, and re-joins all rooms.
-
Cleanup — A background virtual thread periodically removes sessions that haven't been seen within the configured TTL.
If not using Spring Boot auto-configuration:
var store = new SqliteSessionStore();
var interceptor = new DurableSessionInterceptor(
store,
Duration.ofHours(24), // session TTL
Duration.ofMinutes(1) // cleanup interval
);
framework.interceptor(interceptor);| Property | Default | Description |
|---|---|---|
atmosphere.durable-sessions.enabled |
false |
Enable durable sessions |
atmosphere.durable-sessions.session-ttl-minutes |
1440 |
Session time-to-live in minutes (24h) |
atmosphere.durable-sessions.cleanup-interval-seconds |
60 |
Expired session cleanup interval |