API v 0.8
JavaScript

Channels

The Ably Realtime service organises the message traffic within applications into named channels. Channels are the “unit” of message distribution; clients attach to channels to subscribe to messages, and every message published to a unique channel is broadcast by Ably to all subscribers. This scalable and resilient messaging pattern is commonly called pub/sub.

The Ably Realtime client library provides a straightforward API for publishing and subscribing to messages on a channel. If the channel does not exist at the time the client is attached, a channel will be created in the Ably system immediately.

JavaScript
var realtime = new Ably.Realtime('<loading API key, please wait>'); var channel = realtime.channels.get('mud-ate-ago'); channel.subscribe(function(message) { alert('Received: ' + message.data); }); channel.publish('example', 'message data');
Demo Only
Copied!

In order to publish, subscribe to, or be present on a channel, you must first obtain a channel instance and then attach to that channel. In most instances, as a convenience, it is unnecessary to explicitly attach a channel as it will implicitly attached when performing any operation on the channel such as publishing or subscribing.

A Channel object is a reference to a single channel. A channel instance is obtained from the channels collection of the Realtime instance, and is uniquely identified by its unicode string name. Find out more about channel naming

JavaScript
var channel = realtime.channels.get('channelName');
Copied!

Setting channel options and encryption

A set of channel options may also be passed to configure a channel for encryption. Find out more about symmetric message encryption.

JavaScript
Ably.Realtime.Crypto.generateRandomKey(function(err, key) { var options = { cipher: { key: key } }; var channel = realtime.channels.get('channelName', options); });
Copied!

Channels are not pre-configured or provisioned by Ably in advance; they are created on demand when clients attach, and remain active until such time that there are no remaining attached clients. Within the dashboard for your app however, you can pre-configure one or more channel namespaces (i.e. name prefixes), and associate different attributes and access rights with those namespaces. Find out more about channel namespaces.

The following example explicitly attaches to a channel, which results in the channel being provisioned in Ably’s global realtime cluster. This channel will remain available globally until there are no more clients attached to the channel:

JavaScript
realtime.channels.get('chatroom').attach(function() { console.log('"chatroom" exists and is now available globally in every data centre'); });
Copied!

Clients attach to a channel in order to participate on that channel in any way (either to publish, subscribe, or be present on the channel).

Although the attach operation can be initiated explicitly by a client, it is more common for the client to perform a publish or subscribe operation, and the client library will initiate the attach if the channel is not already attached. The client library allows clients to begin publishing messages to a channel as soon as the channel has been created, and messages are queued until such time as the attach has succeeded or failed.

JavaScript
var channel = realtime.channels.get('chatroom'); channel.subscribe('action', function(message) { // implicit attach console.log('Message received '' + message.data); }); channel.publish('action', 'boom!');
Copied!

A channel can exist in any of the following states:

initialized
A Channel object having this state has been initialized but no attach has yet been attempted
attaching
An attach has been initiated by sending a request to Ably. This is a transient state; it will be followed either by a transition to attached or failed
attached
Attach has succeeded. In the attached state a client may publish and subscribe to messages, or be present
detaching
A detach has been initiated on the attached Channel by sending a request to Ably. This is a transient state; it will be followed either by a transition to detached or failed
detached
The Channel, having previously been attached, has been detached
failed
An indefinite failure condition. This state is entered if a Channel error has been received from the Ably service (such as an attempt to attach without the necessary access rights)

The Channel object is an EventEmitter and emits an event whose name is the new state whenever there is a channel state change. As with all events from an EventEmitter in the Ably library, this within the listener function is a reference to an event object whose event property is the name of the event that fired. This allows a listener to listen for all events with a single registration and know, which event fired when it is entered.

JavaScript
channel.on('attached', function() { console.log('channel ' + channel.name + ' is now attached'); });
Copied!

Alternatively a listener may be registered so that it receives all state change events.

JavaScript
var myListener = function() { console.log('channel state is ' + this.event); }); channel.on(myListener);
Copied!

Previously registered listeners can be removed individually or all together.

JavaScript
/* remove the listener registered for a single event */ channel.off('attached', myListener); /* remove the listener registered for all events */ channel.off(myListener);
Copied!

Channel attach and detach operations are asynchronous – after initiating an attach request, the client will wait for a response from Ably that confirms that the channel is established on the service and then trigger a state change event.

There are cases where an attach will fail deterministically, such as if the client doesn’t have the necessary rights to access the channel.

JavaScript
realtime.channels.get('private:chatroom').attach(function(err) { if (err) { console.error('Attach failed: ' + err); } });
Copied!

Connection state change side effects on channels

One or more channel rules may be configured for an app in your dashboard. These are rules which apply to a channel based on its ‘namespace’. The namespace is the first colon-delimited segment of its name (from the start, up to and including, the last character before the :). If the channel name contains no colon, the namespace is the entire channel name.

For example, the following channels are all part of the “public” namespace:

  • public
  • public:events
  • public:news:americas

Note that wildcards are not supported in channel namespaces.

The namespace attributes that can be configured are:

Persist last message
if enabled, the very last message published on a channel will be stored for an entire year, retrievable using the channel rewind mechanism by attaching to the channel with rewind=1. If you send multiple messages atomically in a single protocol message, for example with publish([{...}, {...}, {...}]), you would receive all of them as one message. Only messages are stored, not presence messages. This last message storage is not accessible using the normal history API, only through rewind. Please note that for the message stored, an additional message is deducted from your monthly allocation.
Persist all messages
if enabled, all messages within this namespace will be stored according to the storage rules for your account (24 hours for free accounts). You can access stored messages via the history API. Please note that for each message stored, an additional message is deducted from your monthly allocation.
Identified
if enabled, clients will not be permitted to use (including to attach, publish, or subscribe) matching channels unless they are identified (they have an assigned client ID). Anonymous clients are not permitted to join these channels. Find out more about authenticated and identified clients.
TLS only
if enabled, only clients who have connected to Ably over TLS will be allowed to use matching channels. By default all of Ably’s client libraries use TLS when communicating with Ably over REST or when using our Realtime transports such as Websockets.
Push notifications enabled
If checked, publishing messages with a push payload in the extras field is permitted and can trigger the delivery of a push notification to registered devices for the channel. Find out more about push notifications.
Message interactions enabled
If enabled, messages received on a channel will contain a unique timeserial that can be referenced by later messages for use with message interactions. Find out more about message interactions.

Key or token capabilities can also specify access rights based on channel namespace. Find out more about authentication.

Each message published has an optional event name property and a data property carrying the payload of the message. Various primitive and object types are portably defined and supported in all clients, enabling clients to be interoperable despite being hosted in different languages or environments.

The supported payload types are Strings, JSON objects and arrays, buffers containing arbitrary binary data, and Null objects. Client libraries detect the supplied message payload and encode the message appropriately.

The name property of published messages does not affect the distribution of a channel message to clients but may be used as a subscription filter, allowing a client to register a listener that only sees a subset of the messages received on the channel. When subscribing, a message listener can subscribe to see all messages on the channel or only a subset whose name matches a given name string.

A client can subscribe to all messages on a channel by passing a listener function to the subscribe method. The listener is passed a Message object for each message received.

JavaScript
channel.subscribe(function(message) { console.log('message received for event ' + message.name); console.log('message data:' + message.data); });
Copied!

Alternatively a listener may be registered so that it is called only for messages having a specific event name.

JavaScript
channel.subscribe('myEvent', function(message) { console.log('message received for event ' + message.name); console.log('message data:' + message.data); });
Copied!

Previously registered listeners can be removed individually or all together.

JavaScript
/* remove the listener registered for a single event */ channel.unsubscribe('myEvent', myListener); /* remove the listener registered for all events */ channel.unsubscribe(myListener);
Copied!

Channels expose a publish method whereby a client can publish either a single message or an array of messages to a channel. A listener optionally passed in to the publish method enables the client to know whether or not the operation succeeded.

JavaScript
channel.publish('event', 'This is my payload', function(err) { if(err) { console.log('Unable to publish message; err = ' + err.message); } else { console.log('Message successfully sent'); } });
Copied!

Channels also expose an async version PublishAsync of the Publish call which resumes execution once the message is confirmed received. It is purely for convenience.

Result result = await channel.PublishAsync("event", "payload"); if(result.IsFailure) { Console.WriteLine("Unable to publish message. Reason: " + result.Error.Message); } else { Console.WriteLine("Message published successfully"); }
Copied!

Channels expose a history method providing a means for clients to obtain messages previously sent on the channel. Channel history can be used to return continuous message history up to the exact point a realtime channel was attached.

History provides access to instantaneous “live” history as well as the longer term persisted history for attached channels. If persisted history is enabled for the channel, then messages will typically be stored for 24 – 72 hours. If persisted history is not enabled, Ably retains the last two minutes of message history in memory.

The following example retrieves the first two pages of historical messages published up until the point the channel was attached.

JavaScript
channel.attach(function() { channel.history({ untilAttach: true }, function(err, resultPage) { if(err) { console.log('Unable to get channel history; err = ' + err.message); } else { console.log(resultPage.items.length + ' messages received in first page'); if(resultPage.hasNext()) { resultPage.next(function(err, nextPage) { ... }); } } }); });
Copied!

See the history documentation for further details of the supported query parameters.

Channels expose a presence member which a client can use to obtain channel presence information and to enter and leave the presence channel itself. See the presence documentation for details.

View the Channels and Channel API Reference.