# Rooms Rooms are used to organize and logically separate your users and chat messages into 'rooms'. They are the entry object into using chat and provide access to all other chat features, such as messages, online status and typing indicators. A room can represent a 1:1 chat between an agent and a customer, a private message between two users in a chat application, a large group conversation, or the chat section of a livestream with thousands of users. ## Relationship between rooms and channels It is important to note that each room is backed by a single Ably Pub/Sub channel. You may need to be aware of this when using some [integrations](https://ably.com/docs/chat/integrations) with Ably, such as the [Pulsar](https://ably.com/docs/platform/integrations/streaming/pulsar#creating-pulsar-rule) connectors, or if you are operating in an environment where a Chat SDK is not available. The channel name is the same as the room name with an appended suffix of `::$chat` (e.g `some-room-id::$chat`). In most cases, you will not need to worry about this, as the Chat SDK handles the channel creation and management for you and capabilities can be configured at the room level. ### Message persistence Chat room channels have persistence enabled by default with a retention period of 30 days. This ensures that messages are automatically stored and can be retrieved using the [history feature](https://ably.com/docs/chat/rooms/history). The default 30-day retention period can be extended up to 365 days by [contacting us](https://ably.com/support). This automatic persistence is essential for supporting features such as [message updates](https://ably.com/docs/chat/rooms/messages#update), [message deletions](https://ably.com/docs/chat/rooms/messages#delete), and [message reactions](https://ably.com/docs/chat/rooms/message-reactions), all of which require access to previously sent messages. ## Use a room Users send messages to a room and subscribe to the room in order to receive messages. To get an instance of a chat room, use the [`rooms.get()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Rooms.html#get)[`rooms.get()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/rooms/get%28named%3Aoptions%3A%29)[`rooms.get()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-rooms/get.html) method. It will create a new room instance if one doesn't already exist, or return the existing one if it does. The [`ChatRoomProvider`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.ChatRoomProvider.html) provides access to a specific chat room to all child components in the component tree. Pass in the name of the room to use. If you need to provide further feature configuration, such as enabling occupancy messages, you can pass in an optional [`RoomOptions`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.RoomOptions.html) object to the provider. ```javascript const room = await chatClient.rooms.get('basketball-stream', {occupancy: {enableEvents: true}}); ``` ```react const realtimeClient = new Ably.Realtime({ key: 'your-api-key', clientId: 'clientId' }); const chatClient = new ChatClient(realtimeClient); const App = () => { return ( ); }; ``` ```swift let room = try await chatClient.rooms.get(named: "basketball-stream", options: .init(occupancy: .init(enableEvents: true))) ``` ```kotlin val room = chatClient.rooms.get(roomId = "basketball-stream") ``` ```jetpack val room = chatClient.rooms.get(roomId = "basketball-stream") ``` When you create or retrieve a room using `rooms.get()`, you can provide custom configuration for some features for that room by passing a [`RoomOptions`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.RoomOptions.html)[`RoomOptions`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/roomoptions)[`RoomOptions`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room-options/index.html) object as the second argument. If you do not provide a `RoomOptions` object, the default settings will be used. ```javascript const options: RoomOptions = { typing: { heartbeatThrottleMs: 5000, }, presence: { enableEvents: true, }, occupancy: { enableEvents: true, }, }; const room = await chatClient.rooms.get('basketball-stream', options); ``` ```swift let presence = PresenceOptions(enter: false) let typing = TypingOptions(heartbeatThrottle: 5.0) // seconds // using defaults for reactions and occupancy let options = RoomOptions(presence: presence, typing: typing, occupancy: .init()) let room = try await chatClient.rooms.get(named: "basketball-stream", options: options) ``` ```kotlin val room = chatClient.rooms.get(roomId = "basketball-stream") { typing { heartbeatThrottle = 5.seconds } presence { enableEvents = true } occupancy { enableEvents = true } } ``` ```jetpack val room = chatClient.rooms.get(roomId = "basketball-stream") { typing { heartbeatThrottle = 5.seconds } presence { enableEvents = true } occupancy { enableEvents = true } } ``` The details of the options available to each feature are documented on their respective pages: | Feature | `RoomOption` | Default settings | | ------- | ------------ | ---------------- | | [Presence](https://ably.com/docs/chat/rooms/presence) | `presence.enableEvents` | `true` | | [Occupancy](https://ably.com/docs/chat/rooms/occupancy) | `occupancy.enableEvents` | `false` | | [Typing indicators](https://ably.com/docs/chat/rooms/typing) | `typing.heartbeatThrottleMs` | `10000` | ### Release a room Releasing a room allows the underlying resources to be garbage collected or released. Releasing a room may be optional for many applications. If you have multiple transient rooms, such as in the case of a 1:1 support chat, then it may be more beneficial. Also, proactively disconnecting rather than waiting for the standard two-minute timeout can help reduce costs and improve performance. Once [`rooms.release()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Rooms.html#release)[`rooms.release()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/rooms/release%28named%3A%29)[`rooms.release()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-rooms/release.html) has been called, the room will be unusable and a new instance will need to be created using [`rooms.get()`](#create) if you want to reuse it. ```javascript await rooms.release('basketball-stream'); ``` ```swift try await rooms.release(named: "basketball-stream") ``` ```kotlin rooms.release("basketball-stream") ``` ```jetpack rooms.release("basketball-stream") ``` Note that any unresolved promises from `rooms.get()` will be rejected when `rooms.release()` is called. By default the `ChatRoomProvider` will automatically call [`release()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#release) on the room when it unmounts. Set the [`release`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.ChatRoomProviderProps.html#release) property to `false` to change this behavior and have the room only [detach](#detach) when the component unmounts. You can manually control this attachment behavior using the [`useRoom`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useRoom.html) hook. ## Attach to a room To start receiving messages and events from a room, you need to attach to it. Attaching to a room tells Ably to start streaming messages to the client, and ensures that events are not missed in case of temporary network interruptions. Once an instance of a room has been created using `rooms.get()`, clients attach to it to start receiving messages and events from the room. Use the [`attach()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#attach)[`attach()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/room/attach%28%29)[`attach()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room/attach.html) method on a room to attach to it: The first `ChatRoomProvider` for a given room will automatically call [`attach()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#attach) on the room when it first mounts. Equally, the last `ChatRoomProvider` for a given room will automatically call [`detach()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#detach) on the room when it unmounts. You can also call `attach()` and `detach()` manually using the [`useRoom`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useRoom.html) hook. ```javascript await room.attach(); ``` ```react const MyComponent = () => { const { attach } = useRoom(); return (
); }; ``` ```swift try await room.attach() ``` ```kotlin room.attach() ``` ```jetpack room.attach() ```
As soon as a client is attached to a room, Ably will begin streaming messages and events to them. To receive the messages and events in your application code, you need to add listeners to the events that you are interested in by subscribing, for example using the [`messages.subscribe()`](https://ably.com/docs/chat/rooms/messages#subscribe) method. Add listeners before attaching to avoid missing any messages or events. ### Detach from a room Use the [`detach()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#detach)[`detach()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/room/detach%28%29)[`detach()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room/detach.html) method on a room to detach from it and stop receiving messages and events: ```javascript await room.detach(); ``` ```swift try await room.detach() ``` ```kotlin room.detach() ``` ```jetpack room.detach() ``` By default the `ChatRoomProvider` will automatically call [`release()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#release) on the room when it unmounts. Set the [`release`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.ChatRoomProviderProps.html#release) property to `false` to change this behavior and have the room only [detach](#detach) when the component unmounts. You can manually control this attachment behavior using the [`useRoom`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useRoom.html) hook. Note that automatically detaching from a room will only happen if [`attach`](#attach) is also set to `true`. If a client detaches from a room without de-registering any of their listeners, they can subsequently re-attach at a later point and their listeners will continue to receive messages and events. ## Room status Monitoring the status of a room enables you to track its lifecycle and react accordingly. A room can have any of the following statuses: | Status | Description | | ------ | ----------- | | initializing | The library is initializing the room. This status is only used for React when the room has not yet resolved. | | initialized | The room has been initialized, but no attach has been attempted yet. | | attaching | An attach has been initiated by sending a request to Ably. This is a transient status and will be followed either by a transition to attached, suspended, or failed. | | attached | An attach has succeeded. In the attached status a client can publish and subscribe to messages, and enter the presence set. | | detaching | A detach has been initiated on the attached room by sending a request to Ably. This is a transient status and will be followed either by a transition to detached or failed. | | detached | The room has been detached by the client. | | suspended | The room, having previously been attached, has lost continuity. This is normally due to the client being disconnected from Ably for more than two minutes. The client will automatically attempt to reattach as soon as connectivity is restored. | | failed | An indefinite failure condition. This status is entered if an error has been received from Ably, such as an attempt to attach without the necessary access rights. | Use the [`status`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.RoomStatus.html#status)[`status`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/roomstatus)[`status`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room/status.html) property to check which status a room is currently in: Use the `roomStatus` property to view the current [`Room`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html) status changes. The `roomError` property is its associated error. Any hooks that take an optional listener have these properties available in their response, such as `useMessages` or `useTyping`. It is more common that you will monitor the room status in the specific feature hooks rather than needing to use `useRoom`. These events are related to the room instance of the nearest [`ChatRoomProvider`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.ChatRoomProvider.html). For example, with the `useMessages` hook: ```javascript const currentStatus = room.status; // The error related to the current room status const currentError = room.error; ``` ```react const MyComponent = () => { const { roomStatus, roomError } = useMessages({ listener: (message) => { console.log('Received message: ', message); }, }); return (
Room status is: {roomStatus} Room error is: {roomError}
); }; ``` ```swift let status = room.status ``` ```kotlin val status = room.status ``` ```jetpack val status = room.status ```
You can also subscribe to room status updates by registering a listener. An event will be emitted whenever the status of the room changes. Use the [`room.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#onStatusChange)[`room.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/room/onstatuschange%28%29-s9g)[`room.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room/on-status-change.html) method in a room to register a listener for status change updates: Use the [`collectAsStatus()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/jetpack/chat-extensions-compose/com.ably.chat.extensions.compose/collect-as-status.html) extension function to observe room status changes reactively in Jetpack Compose: ```javascript const { off } = room.onStatusChange((change) => console.log(change)); ``` ```swift let statusSubscription = room.onStatusChange() for await status in statusSubscription { print("Room status: \(status)") } ``` ```kotlin val (off) = room.onStatusChange { statusChange: RoomStatusChange -> println(statusChange.toString()) } ``` ```jetpack const MyComponent = () => { useOccupancy({ onRoomStatusChange: (roomStatusChange) => { console.log('Room status change:', roomStatusChange); }, onDiscontinuity: (error) => { console.log('Discontinuity detected:', error); }, }); return
Occupancy Component
; }; ```