Appearance
Subscriptions
Subscriptions link a WebSocket session to a channel. Each subscription tracks read/write activity and has an optional expiration.
The Subscription Struct
cpp
struct subscription {
boost::uuids::uuid node_id_; // Node that owns this session
boost::uuids::uuid websocket_connection_id_; // Session UUID
boost::uuids::uuid channel_id_; // Channel UUID
std::chrono::system_clock::time_point joined_at_; // When subscribed
std::chrono::system_clock::time_point expires_at_; // When it expires (max = no expiry)
std::atomic<uint64_t> read_count_{0}; // Messages received
std::atomic<uint64_t> write_count_{0}; // Messages sent
};Each subscription is unique per (websocket_connection_id, channel_id) pair — a session cannot subscribe to the same channel twice.
Subscription API
All subscription operations go through clients::registry.
cpp
auto& clients = app.get_state()->of_clients();Creating a Subscription
cpp
clients.add_subscription(
node_id, // This node's UUID
session_id, // WebSocket session UUID
"room-general", // Channel name
std::chrono::system_clock::time_point::max() // Expiration (max = never)
);Removing Subscriptions
cpp
// Remove a single subscription
clients.remove_subscription(session_id, "room-general");
// Remove all subscriptions for a session (called automatically on disconnect)
clients.remove_subscriptions_by_session_id(session_id);
// Remove all subscriptions for a node
clients.remove_subscriptions_by_node_id(node_id);
// Expire a specific subscription (marks as expired without removing)
clients.expire_subscription(session_id, "room-general");Checking Subscription Status
cpp
// Check if a session is subscribed to a channel
bool is_subscribed = clients.has_subscription(session_id, "room-general");
// Get all members of a channel
auto members = clients.get_channel_members(channel_id);Looking Up Subscribers
cpp
// Get all subscribers for a specific channel
auto subs = clients.get_subscriptions_by_channel_id(channel_id);
for (auto& sub : subs) {
fmt::println("Session {} subscribed at {}", sub.websocket_connection_id_, sub.joined_at_);
}
// Get WebSocket connections for a node+channel combination
auto connections = clients.get_websocket_connections_by_node_id_and_channel(node_id, "room-general");Subscription Lifecycle
- Subscribe —
add_subscription()registers the subscription via theOpcode_ClientSubscribehandler. - Deliver —
broadcast_to_channel()sends messages to all subscribers. - Expire — If
expires_at_is reached, the subscription is pruned automatically. - Cleanup — On disconnect,
remove_subscriptions_by_session_id()removes all subscriptions for that session.
The subscriptions are stored in a Boost.MultiIndex container with indexes for fast lookups by node, session, channel, and composite keys.