# Realtime rooms

People with the page open join a room by name and see each other act, live: messages, who's here, a host, and a small shared state.

**When to use it:** Several people have the page open at once and what one does should show up for the others within a second: a live poll, planning poker, a quiz, cursors, a game. Save results that should last in the database.

**Status:** Preview. **Turned on:** On for every space. The space's admins can turn it off in its Settings, under What pages can do.

## How

const room = await cloudtifact.rooms.join(name, { name: displayName }) joins (names: 1 to 40 letters, digits, - or _). room.send(data) reaches everyone else, room.send(data, { to: memberId }) one person; room.on("message", (data, from) => ...). room.members, room.me and room.on("members") say who's here; room.host (room.on("host")) is always someone connected, so one browser can run a quiz or game for everyone. room.set(key, value) and room.on("state") keep shared state that latecomers get. cloudtifact.rooms.count(name) and rooms.list() read live counts without joining.

```html
<p id="who"></p><button id="yes">Yes</button><p id="tally"></p>
<script>
  (async () => {
    const room = await cloudtifact.rooms.join("all-hands", { name: "Mia" });
    const show = () => {
      who.textContent = room.members.filter((m) => !m.away).length + " here";
      // One key per person, so votes cast at the same moment never overwrite each other.
      const yes = Object.keys(room.state).filter((k) => k.startsWith("vote:") && room.state[k] === "yes");
      tally.textContent = yes.length + " said yes";
    };
    room.on("members", show);
    room.on("state", show);
    document.getElementById("yes").onclick = () => room.set("vote:" + room.me.id, "yes");
    show();
  })();
</script>
```

## Limits

- 16 people a room; 100 rooms with people in them and 500 people in rooms per space.
- 30 messages a second per person (send game state 10 to 20 times a second, not every frame); 16 KB a message.
- Shared state: 128 keys, 4 KB a value, 256 KB a room; kept 7 days after the room empties. Save what should last in the database.
- Anyone who can open the page can join its rooms by name, so use a random code for a private session. Members-only spaces' rooms open only through their links.
- It reconnects by itself and keeps the person's id for 15 seconds; sends while reconnecting return false and are dropped.

## Errors

A failed call rejects with an Error whose `code` is one of:

| Code | When |
| --- | --- |
| `room_full` | The room already has 16 people. |
| `space_limit` | The space has too many rooms or people in rooms right now; try later. |
| `rate_limited` | Over 30 messages a second; some were dropped (an "error" event, not a rejection). |
| `too_large` | A message or state value is over its size limit (an "error" event). |
| `capability_off` | The space's admins turned realtime rooms off. |
| `forbidden` | The page's link is invalid or expired, or the space needs its password. |
| `unsupported` | Not a published Cloudtifact page, or no WebSocket in this browser. |
| `invalid` | The room name isn't 1 to 40 letters, digits, - or _. |
| `network` | Couldn't reach the room after a few tries. |

## Cost

Included in every plan, with the limits above.
