Tutorials

Pusher Protocol Adapter Tutorial

The Pusher protocol adapter allows you to interact with Ably using the Pusher protocol. You can use this to gradually migrate across from Pusher to Ably. Rather than having to rewrite all your apps to use Ably client libraries at once, you can use the protocol adapter, then migrate across to Ably client libraries one by one at your leisure, to take advantage of Ably features not supported by the Pusher client libraries such as connection state recovery. Alternatively, you can use a Pusher client library on some platform for which no native Ably client library is available yet.

Full usage notes for the adapter are available at: Using the Ably Pusher Protocol Adapter.

This tutorial assumes that you already have Pusher client libraries set up with Pusher, and just want to convert it to use Ably.

Step 1 – Set up a free account with Ably

In order to run these tutorials locally, you will need an Ably API key. If you are not already signed up, you should sign up now for a free Ably account. Once you have an Ably account:

  1. Log into your app dashboard
  2. Under “Your apps”, click on “Manage app” for any app you wish to use for this tutorial, or create a new one with the “Create New App” button
  3. Click on the “API Keys” tab
  4. Copy the secret “API Key” value from your Root key and store it so that you can use it later in this tutorial

    Copy API Key screenshot

Step 2 – enable Pusher protocol support

  1. Log into your app dashboard
  2. Under “Your apps”, click on “Manage app” for any app you wish to use for this tutorial, or create a new one with the “Create New App” button
  3. Click on the “Settings” tab
  4. Scroll down to “Protocol Adapter Settings”
  5. Tick the “Pusher protocol support” checkbox
  6. Click ‘Save settings’

The dashboard will offer to set up some namespaces for you. Pusher public channels will use the Ably public: namespace, private channels will use the Ably private: namespace, and presence channels will use the Ably presence: namespace. Click “Create default namespaces” to set these up, which will let you change settings, such as whether messages are persisted, for each namespace.

Note on Security

Normally, you cannot connect to the Ably service at all without a complete API key, or a token derived from one. When Pusher protocol support is enabled, you can connect to public channels with only the Ably key name. So you should only enable Pusher support on an app if you’re using Pusher client libraries with that app.

Step 3 – Point your client libraries to Ably

You’ll need to modify the client library initializer by replacing your Pusher app key with the part of your Ably API key before the : (so if your API key is appid.keyid:keysecret, you’d use appid.keyid). You’ll also need to add some things to the options object, as follows:

var pusher = new Pusher('appid.keyid', {
  wsHost       : 'realtime-pusher.ably.io',
  httpHost     : 'realtime-pusher.ably.io',
  disableStats : true,
  encrypted    : true
});

See this step in Github

These are in addition to whatever options you were using already, such as authEndpoint.

You’ll need to modify the client library initializer by replacing your Pusher app key with the part of your Ably API key before the : (so if your API key is appid.keyid:keysecret, you’d use appid.keyid), and the Pusher secret with the part of your API key after the :. You’ll also need to add a few other things to the initializer, as follows. Note that this example is for the Pusher node REST library; if using the realtime library, even in node, select ‘javascript’ from the ‘Show tutorial in:’ bar above.

var pusher = new Pusher({
  appId     : 'appid',
  key       : 'appid.keyid',
  secret    : 'keysecret',
  host      : 'rest-pusher.ably.io',
  encrypted : true
});

See this step in Github

You’ll need to modify the client library initializer by replacing your Pusher app key with the part of your Ably API key before the : (so if your API key is appid.keyid:keysecret, you’d use appid.keyid), and the Pusher secret with the part of your API key after the :. You’ll also need to add a few other things to the initializer, as follows.

Pusher::Client.new(
  app_id:    'appid',
  key:       'appid.keyid',
  secret:    'keysecret',
  host:      'rest-pusher.ably.io',
  encrypted: true
)

See this step in Github

If we don’t have an example in the language you’ll be using, check the Pusher documentation for that library to find the equivalent options to the ones in the javascript example (for realtime libraries) or the ruby or nodejs example (for REST libraries) above.

Step 4 – interoperability between Pusher and Ably client libraries

Behind the scenes, the adapter uses the normal Ably service, so you can use Pusher and Ably client libraries side by side, and they’ll interoperate seamlessly. The main thing you need to be aware of is channel name translation.

Ably and Pusher both have various (incompatible) restrictions on channel names, and use namespaces very differently. So when using the adapter, channel names are mapped. For example if you connect to the channel “foo” using the Pusher adapter, it will actually use the Ably channel “public:foo”; and if you want to communicate with the Pusher client library from an Ably client library, it would need to connect to that channel.

The translation rules are as follows:

  • Pusher public channels (no prefix) are mapped to the the Ably public: namespace.
  • Pusher private channels (private- prefix) are mapped to the the Ably private: namespace.
  • Pusher presence channels (presence- prefix) are mapped to the the Ably presence: namespace.
  • Ably channels not in any of the public:, private:, or presence: namespaces get a private-ablyroot- prefix when seen from a Pusher client.
  • Colons are banned in Pusher channel names, but are important in Ably channel names, as they act as the namespace separator. So the adapter maps semicolons to colons: semicolons in Pusher channel names become colons in Ably channel names, and vice versa. (This means you will not be able to access any Ably channels which have semicolons in their name).

A few examples:

Pusher adapter channel Actual Ably channel
presence-foo presence:foo
private-foo private:foo
foo public:foo
foo;bar public:foo:bar
private-ablyroot-foo foo
private-ablyroot-foo;bar foo:bar
Interoperability example

Here’s some code that subscribes to a channel from the Pubnub client library, then publishes to it from the Ably client library:

/* Subscribe to the 'some_channel' channel. This is actually an
 * Ably channel called 'public:some_channel' */
var channel = pusher.subscribe('some_channel');
channel.bind('message_name', function(data) {
  alert("Received a message: " + JSON.stringify(data));
});

/* Publish a message with the Ably client */
var ablyChannel = ably.channels.get('public:some_channel');
ablyChannel.publish('message_name', { 'some': ['JSON', 'data'] });

See this step in Github

Here’s some code that subscribes to a channel from the Ably node client library, then publishes to it from the Pusher node client library:

/* Subscribe to the 'public:some_channel' channel with the Ably client */
const ablyChannel = ably.channels.get('public:some_channel');
ablyChannel.subscribe(function(message) {
  console.log('Ably client received a message: ' + message.name + ', data: ' + JSON.stringify(message.data));
});

/* Publish to the 'some_channel' channel with the Pusher client.
 * This is a public channel, so the real channel name is 'public:some_channel' */
pusher.trigger('some_channel', 'eventName', { 'Some': 'JSON data' });

See this step in Github

Here’s some code that subscribes to a channel from the Ably ruby client library, then publishes to it from the Pusher ruby client library:

# Subscribe to the 'public:some_channel' channel with the Ably client
ablyChannel = ably.channels.get('public:some_channel')
ablyChannel.subscribe do |message|
  puts "Ably client received a message: #{message.name} - #{message.data.inspect}"
end

# Publish to the 'some_channel' channel with the Pusher client.
# This is a public channel, so the real channel name is 'public:some_channel'
pusher.trigger('some_channel', 'event_name', {some: 'data sent by the Pusher client library'})

See this step in Github

Download tutorial source code

The complete source code of a working example of Ably and Pusher client libraries communicating with each other is available on Github.

We recommend that you clone the repo locally:

git clone https://github.com/ably/tutorials.git

Checkout the tutorial branch:

git checkout pusher-adapter-javascript

And then run the demo locally by adding your Ably API key to example.html and opening the page in your browser. (Make sure you’ve completed the preliminary steps above first; in particular, step 2 (enabling Pusher protocol support in your dashboard))

The complete source code of a working example of Ably and Pusher client libraries communicating with each other is available on Github.

We recommend that you clone the repo locally:

git clone https://github.com/ably/tutorials.git

Checkout the tutorial branch:

git checkout pusher-adapter-nodejs

And then run the demo locally by adding your Ably API key to example.js and running the demo node example.js. (Make sure you’ve completed the preliminary steps above first; in particular, step 2 (enabling Pusher protocol support in your dashboard))

The complete source code of a working example of Ably and Pusher client libraries communicating with each other is available on Github.

We recommend that you clone the repo locally:

git clone https://github.com/ably/tutorials.git

Checkout the tutorial branch:

git checkout pusher-adapter-ruby

And then run the demo locally by adding your Ably API key to example.rb and running the demo with bundle exec ruby example.rb. (Make sure you’ve completed the preliminary steps above first; in particular, step 2 (enabling Pusher protocol support in your dashboard))

Next steps

  1. Review the many reasons to migrate from Pusher to Ably
  2. Full usage notes for the Pusher adapter are available at: Using the Ably Pusher Protocol Adapter.
  3. Consider gradually transitioning to the Ably client libraries, for platforms which have them. While using the adapter gives you some of the advantages of Ably over Pusher (eg inter-region message federation), many others (e.g. connection state continuity, fallback host support, accessing history, flexible channel namespaces, powerful token authentication) require the use of Ably client libraries.
  4. Get in touch if you need help