# Connections When you [instantiate](https://ably.com/docs/chat/setup.md#instantiate) a client, a realtime connection is established and maintained with Ably. You can interact with the connection using the `ChatClient.connection` object in order to monitor a client's connection status. ## Connection statuses A connection can have any of the following statuses: | Status | Description | |--------|-------------| | `initialized` | A connection object has been initialized but not yet connected. | | `connecting` | A connection attempt has been initiated, this status is entered as soon as the SDK has completed initialization, and is re-entered each time connection is re-attempted following disconnection. | | `connected` | A connection exists and is active. | | `disconnected` | A temporary failure condition when no current connection exists. The disconnected status is entered if an established connection is dropped, or if a connection attempt is unsuccessful. | | `suspended` | A long term failure condition when no current connection exists because there is no network connectivity or available host. The suspended status is entered after a failed connection attempt if there has then been no connection for a period of two minutes. In the suspended status, an SDK will periodically attempt to open a new connection every 30 seconds. Rooms will be reattached on a successful reconnection, however message history will not be automatically recovered. | | `closing` | An explicit request by the developer to close the connection has been sent to the Ably service. If a reply is not received from Ably within a short period of time, the connection is forcibly terminated and the connection status becomes Closed. | | `closed` | The connection has been explicitly closed by the client. In the closed state, no reconnection attempts are made automatically. No connection state is preserved by the service or the library. | | `failed` | This status is entered if the SDK encounters a failure condition that it cannot recover from. This may be a fatal connection error received from the Ably service, such as an attempt to connect with an incorrect API key, or some local terminal error, such as that the token in use has expired and the SDK does not have any way to renew it. | Use the [`status`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Connection.html#status)[`status`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/connectionstatus)[`status`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-connection/status.html) property to check which status a connection is currently in: Use the [`currentStatus`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-react.UseChatConnectionResponse.html#currentStatus) property returned in the response of the [`useChatConnection`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/functions/chat-react.useChatConnection.html) hook to check which status a connection is currently in: ```javascript const connectionStatus = chatClient.connection.status; // The error related to the current status const error = chatClient.connection.error; ``` ```react import { useChatConnection } from '@ably/chat/react'; const MyComponent = () => { const { currentStatus } = useChatConnection({ onStatusChange: (statusChange) => { console.log('Connection status changed to: ', statusChange.current); }, }); return
Connection status is: {currentStatus}
; }; ``` ```swift let status = chatClient.connection.status ``` ```kotlin val connectionStatus = chatClient.connection.status ``` ```jetpack val connectionStatus = chatClient.connection.status ```
Hooks related to chat features, such as `useMessages` and `useTyping`, also return the current `connectionStatus` in their response. ```react import { useMessages } from '@ably/chat/react'; const MyComponent = () => { const { connectionStatus } = useMessages({ listener: (message) => { console.log('Received message: ', message); }, }); return
Current connection status is: {connectionStatus}
; }; ```
Listeners can also be registered to monitor the changes in connection status. Any hooks that take an optional listener to monitor their events, such as typing indicator events in the `useTyping` hook, can also register a status change listener. Changing the value provided for a listener will cause the previously registered listener instance to stop receiving events. All messages will be received by exactly one listener.
Use the [`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Connection.html#onStatusChange)[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/connection/onstatuschange%28%29-76t7)[`connection.onStatusChange()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-connection/on-status-change.html) method 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) composable function to observe the connection status: ```javascript const { off } = chatClient.connection.onStatusChange((change) => console.log(change)); ``` ```react import { useOccupancy } from '@ably/chat/react'; const MyComponent = () => { useOccupancy({ onConnectionStatusChange: (connectionStatusChange) => { console.log('Connection status change:', connectionStatusChange); }, }); return
Occupancy Component
; }; ``` ```swift let subscription = chatClient.connection.onStatusChange() for await statusChange in subscription { print("Connection status changed to: \(statusChange.current)") } ``` ```kotlin val (off) = chatClient.connection.onStatusChange { statusChange: ConnectionStatusChange -> println(statusChange.toString()) } ``` ```jetpack import androidx.compose.material.* import androidx.compose.runtime.* import com.ably.chat.ChatClient import com.ably.chat.extensions.compose.collectAsStatus @Composable fun MyComponent(chatClient: ChatClient) { val connectionStatus by chatClient.connection.collectAsStatus() LaunchedEffect(connectionStatus) { println("Connection status changed to: $connectionStatus") } Text("Connection status: $connectionStatus") } ```
Use the `off()` function returned in the `onStatusChange()` response to remove a listener: ```javascript off(); ``` ```kotlin off() ``` ## Handle connection discontinuity If a client briefly loses connection to Ably, for example when driving through a tunnel, the SDK will attempt to recover the connection. If the disruption lasts for less than 2 minutes, then on reconnection the SDK will automatically reattach to any rooms and replay any missed messages. During periods of discontinuity greater than 2 minutes then you will need to take steps to recover any missed messages, such as by calling [history](https://ably.com/docs/chat/rooms/history.md). The Chat SDK provides an `onDiscontinuity()` handler exposed via the Room object to assist with this. This method enables you to register a listener that will be notified when discontinuity occurs in the room so that you can handle it, as needed. Any hooks that take an optional listener to monitor their events, such as typing indicator events in the `useTyping` hook, can also register a listener to be notified of, and handle, periods of discontinuity. Use the [`discontinuityAsFlow()`](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/discontinuity-as-flow.html) extension function to observe discontinuity events as a Flow in Jetpack Compose: For example, for messages: ```javascript const { off } = room.onDiscontinuity((reason: ErrorInfo) => { // Recover from the discontinuity }); ``` ```react import { useState } from 'react'; import { useMessages } from '@ably/chat/react'; const MyComponent = () => { useMessages({ onDiscontinuity: (error) => { console.log('Discontinuity detected:', error); }, }); return
...
; }; ``` ```swift let subscription = room.onDiscontinuity() for await error in subscription { print("Recovering from the error: \(error)") } ``` ```kotlin val (off) = room.onDiscontinuity { reason: ErrorInfo -> // Recover from the discontinuity } ``` ```jetpack import androidx.compose.runtime.* import com.ably.chat.Room import com.ably.chat.discontinuityAsFlow @Composable fun MyComponent(room: Room) { LaunchedEffect(room) { room.discontinuityAsFlow().collect { error -> // Recover from the discontinuity println("Discontinuity detected: $error") } } } ```
Use the `off()` function returned in the `onDiscontinuity()` response to remove a listener: ```javascript off(); ``` ```kotlin off() ``` The discontinuity handler is accessible via the [Room](https://sdk.ably.com/builds/ably/ably-chat-js/main/typedoc/interfaces/chat-js.Room.html#onDiscontinuity)[Room](https://sdk.ably.com/builds/ably/ably-chat-swift/main/AblyChat/documentation/ablychat/room)[Room](https://sdk.ably.com/builds/ably/ably-chat-kotlin/main/dokka/chat/com.ably.chat/-room/index.html) object.