Sessions¶
The package tracks every active WebSocket connection as a Session record.
This enables multi-device support (a single user connected on multiple devices
simultaneously) and clean session management across reconnections.
How Sessions Work¶
On connect —
channel_cleanup()runs first, removing any expired session channel names from all channel groups (preventing message delivery to disconnected clients). Thenchannel_setup()registers a newSessionrecord for the current connection and restores the user’s group memberships from cache.During the connection — The client sends periodic
session.heartbeatevents to update thelast_seentimestamp and keep the session alive.On disconnect —
channel_cleanup()runs again to remove the expired session from groups.
Session Model Fields¶
Field |
Description |
|---|---|
|
FK to |
|
The Django Channels layer channel name for this specific connection. |
|
Timestamp of the last heartbeat. Used to determine if the session is active. |
Inactivity Threshold¶
Sessions older than INACTIVITY_THRESHOLD seconds (default: 60) are
considered expired. Expired sessions are:
Removed from all channel groups during the next connection’s cleanup phase.
Excluded from
get_active_sessions()so messages are not sent to disconnected channels.
The default of 60 seconds works well for most applications. Adjust it in settings if your use case requires longer idle periods:
REALTIME_CHAT_MESSAGING = {
"INACTIVITY_THRESHOLD": 300 # 5 minutes
}
Heartbeat¶
Clients must send heartbeats to prevent their session from expiring. The recommended interval is every 15–30 seconds (2–3 times within the default 60-second threshold).
Client payload:
{
"event_type": "session.heartbeat",
"data": {}
}
The server responds immediately:
{"status": "success"}
No need to await or listen for this response on the frontend — it is purely
confirmatory.
Multi-Device Support¶
When a user connects from multiple devices, each connection creates its own
Session record with a unique channel_name. When a message is sent to a
room, the package fetches all active sessions for each recipient and adds
every channel name to the broadcast group. This means all connected devices
receive every message simultaneously.
Group membership cache (user:<user_id>:groups) is keyed per user, not per
session. All of the user’s sessions share the same group memberships, which is
why restoring groups on reconnect works correctly for any device.
Cache Storage¶
Group memberships are stored in Django’s cache under the key
user:<user_id>:groups as a JSON-serialised list. This cache entry has no
expiration (timeout=None) so memberships survive application restarts.
When a user joins or leaves a room, the cache is updated atomically via
add_group_to_user_groups() or remove_group_from_user_groups(). The cache
entries are the authoritative source for group restoration; the Session
database records are the authoritative source for active channel names.