Presence

Channels whose names start with presence- are private channels that also know who is in them. Use them for "who's online", avatars in a document, or player lists.

Identify members

The token that grants a presence channel must carry the user's id (uid), and can carry public info that the other members see:

server.ts
const token = await thunderclap.token({
  uid: req.user.id,
  info: { name: req.user.name, avatar: req.user.avatarUrl },
  channels: ["presence-room-*"],
});

info is at most 1 KB as JSON. A user connected from several tabs or devices counts as one member.

Track members

client.ts
const room = thunderclap.subscribe<RoomEvents, { name: string }>("presence-room-42");

room.on("subscribed", () => {
  console.log("me", room.me, "everyone", [...room.members.values()]);
});
room.on("member_added", (member) => console.log(member.info?.name, "joined"));
room.on("member_removed", (member) => console.log(member.info?.name, "left"));
  • members is a Map keyed by user id, and includes the current user (room.me).
  • After a reconnect, the joins and leaves the client missed are reported as member_added and member_removed.
  • Presence changes don't use sequence numbers, so they never cause a gap.

Limits

A presence channel holds up to 100 members. Beyond that, new members are refused with error 4305.

To mirror presence in your own database, use the member_added and member_removed webhooks.