Tutorials

Pubnub Protocol Adapter Tutorial

The Pubnub protocol adapter allows you to interact with Ably using the Pubnub protocol. You can use this to gradually migrate across from Pubnub 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 Pubnub client libraries, such as the ability to use websockets (Pubnub client libraries support long-polling only). Alternatively, you can use a Pubnub client library on some platform for which no native Ably client library is available yet, such as Arduino.

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

This tutorial assumes that you already have Pubnub client libraries set up with Pubnub, 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 – Point your client libraries to Ably

You’ll need to modify the client library initializer by replacing both the publish and subscribe key with your Ably API key. You’ll also need to add some things to the options object, as follows:

var apiKey = "<your Ably API key>";
var pubnub = PUBNUB({
  publish_key        : apiKey,
  subscribe_key      : apiKey,
  origin             : 'pubnub.ably.io',
  ssl                : true,
  no_wait_for_pending: true
});

(In addition to whatever options you would normally use).

You’ll need to modify the client library initializer by replacing both the publish and subscribe key with your Ably API key. You’ll also need to add some things to the options object, as follows:

api_key = "<your Ably API key>"
pubnub = Pubnub.new(
  :subscribe_key => api_key,
  :publish_key   => api_key,
  :origin        => 'pubnub.ably.io',
  :ssl           => true
)

See this step in Github

Don’t try to use different Ably API keys for the publish_key and subscribe_key. Unlike Pubnub, Ably does not use different keys for publish and subscribe; instead, capabilities are connection-oriented, and the Adapter will use whatever you pass as the subscribe_key to create the Ably connection. If that key does not have publish capabilities, you will not be able to publish, whatever the publish_key has.

If we don’t have an example in the language you’ll be using, check the Pubnub documentation for that library to find the equivalent options to the ones in the Javascript example (for realtime libraries) or the Ruby or Node.js example (for REST libraries) above.

Step 3 – check you’re not using any unsupported features

The Pubnub adapter does not yet support PAM, wherenow, channel groups, backfill subscribes, or stream filters. If you use any of these, let us know and we can advise on Ably-supported ways to achieve the same goal. (For example, instead of PAM we have our token authentication system).

Also note that since the adapter has to translate every Pubnub operation to the equivalent Ably operation, some Pubnub operations can be quite expensive, in terms of the time it takes to do them and the number of API requests they count against your package quota. For example, if you do a ‘global herenow’ request (which returns every presence member in every active channel in your app), behind the scenes the adapter will do a request for a list of active channels, followed by a presence request for each of those channels, for a total of n+1 requests for n active channels.

Step 4 – interoperability between Pubnub and Ably client libraries

Behind the scenes, the adapter uses the normal Ably service, so you can use Pubnub and Ably client libraries side by side, and they’ll interoperate. For example, here’s some code that subscribes to the same channel from both Pubnub and Ably client libraries, then publishes using both.

var channelName = 'some_channel';

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

/* Subscribe to the 'some_channel' channel with the Pubnub client */
pubnub.subscribe({
  channel : channelName,
  message : function(message) {
    log('Pubnub client received a message: ' + JSON.stringify(message));
  }
});

/* Publish a message with the Ably client
 * Note that we use null as the message name, since any message
 * name will be ignored by the Pubnub client */
ablyChannel.publish(null, { 'Some': 'JSON data sent by the Ably client library' });

/* Publish a message with the Pubnub client */
pubnub.publish({
  channel : channelName,
  message : { 'Some': 'JSON data sent by the Pubnub client library' }
});
channel_name = 'some_channel'

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

# Subscribe to the 'some_channel' channel with the Pubnub client
pubnub.subscribe(
  channel: channel_name,
) do |env|
  puts "Pubnub client received a message: #{env.message.inspect}"
end

# Publish a message with the Ably client
# Note that we use null as the message name, since any
# message name will be ignored by the Pubnub client
ablyChannel.publish(nil, { some: 'data sent by the Ably client library' })

# Publish a message with the Pubnub client
pubnub.publish(
  channel: channel_name,
  message: { some: 'data sent by the Pubnub client library' }
) {}

See this step in Github

There are a few things to be aware of:

Publishing and subscribing

  • Pubnub does not have a concept of a message name. So A publish using the Pubnub adapter will leave the Ably message name blank, and message name is not visible to Pubnub adapter subscribers. Pubnub message content is mapped to Ably message data (the payload).
  • Commas are valid in Ably channel names, but Pubnub uses commas as delimiters. So Ably channels with commas in them will not be accessible to Pubnub clients.

Presence and state

  • Pubnub’s UUID is mapped to Ably’s clientId.
  • Pubnub considers the same UUID to be the same (in terms of membership of the presence set); Ably considers the same clientid on different connections to be different. (If using the adapter to get the state for a clientId, if there are multiple members in the set with the same clientId, the adapter will just pick one).
  • Pubnub’s member state is mapped to Ably’s presence data. With presence data, member aren’t permitted to change other members’ presence data. So each client can only set its own state, not other people’s.

Connections

  • In Pubnub’s model, message continuity is available for ‘5-20 minutes’ and up to 100 messages. To provide compatibility with this, the Pubnub adapter will stay connected and attached to your channels for 5 minutes after the last subscribe long poll it receives. After 5 minutes, the adapter will disconnect from Ably, and any subsequent subscribe poll will be treated as a new connection (and will get messages from that point in time onwards).
  • During development, using a lot of different uuids (eg using the unique_uuid option of the Pubnub js lib to generate a new uuid on each page refresh) may result in connections racking up quickly, as each will stay alive for at least 5 minutes. We recommend avoiding that option, at least during development.

Download tutorial source code

The complete source code of a working example of Ably and Pubnub 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 pubnub-adapter-javascript

And then run the demo locally by adding your Ably API key to example.html and opening the page in your browser.

The complete source code of a working example of Ably and Pubnub 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 pubnub-adapter-nodejs

And then run the demo locally by adding your Ably API key to example.js and running the demo node example.js

The complete source code of a working example of Ably and Pubnub 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 pubnub-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

Next steps

  1. Review the many reasons to migrate from Pubnub to Ably
  2. Full usage notes for the Pubnub adapter are available at: Using the Ably Pubnub Protocol Adapter.
  3. Consider gradually transitioning to the Ably client libraries, for platforms which have them. They will be faster and more efficient: faster because native Ably libraries can use websockets as a transport (Pubnub can only do long polling), and more efficient because using native Ably libraries avoids the overhead of protocol translation.
  4. Get in touch if you need help

Get started now with our free plan

It includes 3m messages per month, 100 peak connections, 100 peak channels, and loads of features.

Create your free account