Connections overview
Clients establish and maintain a connection to the Ably service using the most efficient transport available, typically WebSockets.
Connection multiplexing
Ably SDKs operate and multiplex all channel traffic over a single connection. This means you can publish and subscribe to messages on any number of channels simultaneously using just one transport connection. This approach:
- Maximizes throughput by efficiently utilizing the available connection.
- Minimizes bandwidth consumption by avoiding multiple connection overhead.
- Reduces power usage by maintaining fewer active connections.
All Ably client libraries support multiplexing by default when using the realtime interface. You can dynamically subscribe and unsubscribe from channels at any time without needing to establish new connections.
Once connected, clients can monitor and manage their connection state.
Create a connection
Ably SDKs open and maintain a connection to the Ably realtime servers on instantiation, which can be interacted with by using the Connection object. The lifecycle of connections are reported by different connection states to simplify monitoring and managing connections.
This example relies on the default auto-connect behavior of the SDK, checking for when the connection state is connected event:
1
2
3
4
5
6
7
8
9
10
11
// Using callbacks
const ably = new Ably.Realtime({ 'demokey:*****' });
ably.connection.on('connected', () => {
console.log('Connected to Ably!');
});
// Using promises
const Ably = require('ably');
const ably = new Ably.Realtime('demokey:*****');
await ably.connection.once('connected');
console.log('Connected to Ably!');If you're not using the SDK's auto-connect feature you can also connect with connect() to manually connect unless the state is already connected or connecting.
Explicitly calling connect is unnecessary unless the ClientOptions attribute autoConnect is false. Unless already connected or connecting, this method causes the connection to open, entering the connecting state. To manually attempt to open a connection you call the connect() function: ably.connect().
Monitor connections to an app
Connection monitoring allows you to view and manage the states of connections to Ably, showing events for individual people connecting and disconnecting. The developer console in your Ably account also shows these events.
This feature is intended for debugging, so once the number of new connections exceeds the number of messages per second permitted by the lifecycle channel, new events will be dropped. This means if you want a definitive list of everyone using your app you'd be best using token authentication to create your own 'auth server'.
The Ably dashboard contains a developer console. In the developer console you can view connection events.
Connection IDs
A connection ID is a unique identifier given to a connection, allowing for identifying and specifying particular connections.
An active connection ID is guaranteed to be unique in the Ably system whilst it is active, i.e. no other connection will share that connection ID. However, Ably reserves the right to generate a new connection ID later that may be the same as a previously discarded connection ID (once the connection is closed). Therefore customers are advised to not use the connection ID as a perpetual unique identifier as it is possible that a connection ID may be used many times.
Connection metachannels
Metachannels are a namespace of channels beginning with the [meta] qualifier, distinguishing them from regular channels. For connections there is a specific [meta]connection.lifecycle channel that publishes messages about the lifecycle of realtime connections. The connection lifecycle consists of a number of connection states that can be observed and interacted with using methods available on the connection object.
Heartbeats
Heartbeats enable Ably to identify clients that abruptly disconnect from the service, such as where an internet connection drops out or a client changes networks.
Ably sends a heartbeat to connected clients every 15 seconds. If a client goes more than 25 seconds without seeing any server activity from Ably, it assumes that something has gone wrong with the connection and the connection state will become disconnected. The 25 seconds the client waits is the heartbeat interval plus a 10 second margin of error to allow for network delays.
Ably also uses this mechanism to detect dropped client connections, though some details vary depending on the transport used.
It is important to note that this mechanism is only used when something disrupts communication and does not properly terminate the TCP connection. It isn't used when a connection is deliberately closed or disconnected, for example by calling the close() method or being disconnected by the server.
The 15 second interval between heartbeats is used to strike a balance between optimizing battery usage for client devices and the time it takes to identify a dropped or unstable connection.
The interval between heartbeats can be customized if your app requires increased battery preservation or to identify dropped connections more quickly. Set a value between 5000 and 1800000 milliseconds (5 seconds and 30 minutes) using the heartbeatInterval parameter within the transportParams property of the clientOptions object.
Using a higher heartbeatInterval can increase the time taken for the Ably service and the client itself to identify a connection has dropped when an abrupt disconnect occurs. The number of concurrent connections may also appear higher as it can take longer to terminate dropped connections. Although heartbeatInterval can be set as high as 30 minutes, Ably does not recommend setting it this high.
You can also call ping() to send a heartbeat ping to Ably, which can be useful for measuring the true round-trip latency to the Ably server.
The following example code demonstrates establishing a connection to Ably with a heartbeatInterval of 10 seconds:
1
2
3
4
5
6
const ably = new Ably.Realtime(
{
key: 'demokey:*****',
transportParams: { heartbeatInterval: 10000 }
}
);Browser page unload behavior
In browser environments, ably-js automatically handles page unload events to ensure connections are properly closed when users navigate away or close pages.
Default beforeunload behavior
By default, the Ably Pub/Sub JavaScript SDK adds a listener for the beforeunload event to cleanly close connections before a page is closed. This provides orderly behavior where:
- Connections are seen as having closed immediately by Ably servers.
- Presence members associated with the connection are seen by all users as having left immediately.
If a connection to Ably is not explicitly closed when there is a page unload event, then the connection state is preserved by Ably for 2 minutes. Preserving connection state for 2 minutes when there is an unexpectedly dropped connection provides the opportunity for the client to reconnect and resume the connection without losing any messages.
Reliability considerations
The beforeunload event can be unreliable and is not guaranteed to fire under certain circumstances:
- The event may fire but the page is subsequently not disposed of (navigation can be cancelled).
- The handler in ably-js that closes a connection on a
beforeunloadevent is hazardous unless the application developer is certain that there is no case wherebeforeunloadfires, but the page is subsequently not unloaded. - Recent releases of Chrome (version 108+) have introduced a Memory Saver feature that can cause pages to be discarded without firing
beforeunloadevents.
Chrome Memory Saver impact
Chrome's Memory Saver feature assists with controlling the browser's memory footprint by discarding inactive tabs. This significantly increases the frequency of pages being discarded, which:
- Causes JavaScript execution to stop without opportunity to intercept the event.
- Prevents connections from closing immediately since
beforeunloaddoesn't fire. - Results in longer delays before Ably recognizes the connection has closed.
- Affects presence members leaving immediately.
Managing connection lifecycle
To ensure predictable connection closure behavior, consider these options:
Set closeOnUnload:false in ClientOptions when initializing the library:
1
2
3
4
const ably = new Ably.Realtime({
key: 'your-api-key',
closeOnUnload: false
});Manage connection lifecycle explicitly by calling close() on the Ably realtime instance when it's no longer needed:
1
2
// When your application determines the connection should close
ably.close();Disable Chrome Memory Saver globally or on a site-by-site basis in browser settings if the feature is impacting your application's behavior.
Close a connection
A connection to Ably should be closed once it is no longer needed. Note that there is a 2 minute delay before a connection is closed, if the close() method hasn't been explicitly called. This is important to consider in relation to the number of concurrent connections to your account.
The following code sample explicitly closes the connection to Ably by calling the close() method and prints the message Closed the connection to Ably:
1
2
ably.close(); // runs synchronously
console.log('Closed the connection to Ably.');