Client: Channels
Subscribe to real-time messages published by the server to named channels. Supports optional history on initial join.
Subscribing to a channel
const { success, history } = await client.subscribeChannel(
"news:global",
(message) => {
console.log("Live message:", message);
}
);
if (!success) {
console.error("Subscription failed (guarded?)");
}
The first argument is the channel name. The second is a callback for incoming messages.
With message history
You can optionally request recent messages when subscribing:
const { success, history } = await client.subscribeChannel(
"events:dashboard",
(message) => {
console.log("Live update:", message);
},
{ historyLimit: 5 }
);
history.forEach((msg) => {
const parsed = JSON.parse(msg);
renderHistoricalEvent(parsed);
});
History is only available if the server explicitly stores it: publishToChannel(, , historyLimit)
.
With message history since a specific point
If persistence is enabled for a channel, you can request messages since a specific timestamp or message ID:
// Get messages since a specific timestamp (milliseconds since epoch)
const { success, history } = await client.subscribeChannel(
"events:dashboard",
(message) => {
console.log("Live update:", message);
},
{
historyLimit: 100,
since: 1682450400000,
}
);
// Or get messages since a specific message ID
const { success, history } = await client.subscribeChannel(
"events:dashboard",
(message) => {
console.log("Live update:", message);
},
{
historyLimit: 100,
since: "message-id-123",
}
);
The since
parameter requires persistence to be enabled for the channel on
the server using enablePersistenceForChannels()
.
Retrieving channel history without subscribing
You can retrieve historical messages from a channel without subscribing to it:
// Get the most recent messages
const { success, history } = await client.getChannelHistory(
"events:dashboard",
{
limit: 50,
}
);
// Get messages since a specific timestamp
const { success, history } = await client.getChannelHistory(
"events:dashboard",
{
limit: 50,
since: 1682450400000,
}
);
// Get messages since a specific message ID
const { success, history } = await client.getChannelHistory(
"events:dashboard",
{
limit: 50,
since: "message-id-123",
}
);
// Process the historical messages
history.forEach((msg) => {
const parsed = JSON.parse(msg);
renderHistoricalEvent(parsed);
});
Unsubscribing
To stop receiving updates:
await client.unsubscribeChannel("news:global");
Message format
Channel messages are always sent as raw strings.
If your server publishes structured data (e.g. JSON.stringify(...)
), you must parse it yourself:
client.subscribeChannel("alerts", (msg) => {
try {
const data = JSON.parse(msg);
switch (data.type) {
case "alert":
showAlert(data.message);
break;
case "announcement":
renderBanner(data.content);
break;
default:
console.warn("Unknown message type:", data);
}
} catch (e) {
console.error("Failed to parse channel message:", e);
}
});
Use cases
- Notifications
- Alerts, banners, user-specific pushes
- Live dashboards
- Server stats, performance metrics, monitoring feeds
- Broadcasting
- Build logs, event updates, task progress
- Chat applications
- Message history, pagination, catching up on missed messages
- Activity feeds
- Loading historical activities and receiving real-time updates
For presence indicators, typing status, and ephemeral per-user state, use presence instead.
Best practices
- Unsubscribe when done
- Frees resources and avoids duplicate subscriptions
- Parse carefully
- Messages are strings — use
try/catch
when parsing JSON
- Messages are strings — use
- Resubscribe on reconnect
- Keep a list of active channels and restore them after connection loss
- Use pagination for large history
- For channels with extensive history, use
getChannelHistory
with thesince
parameter to implement pagination
- For channels with extensive history, use
- Consider timestamp format
- When using
since
with a timestamp, use milliseconds since epoch (e.g.,Date.now()
)
- When using
- Error handling
- Always check the
success
flag when retrieving history, as persistence might not be enabled for all channels
- Always check the