Migrating from PubNub

Ably provides the flexibility to migrate from PubNub progressively or all at once. The fastest we’ve seen someone migrate is a few hours.

Our protocol adapter takes care of all the background translation, you simply change your API key. You can also use a PubNub client library via this adapter to work on some platforms for which no Ably client library SDK is available yet.


PubNub - Ably Protocol Adapter

Full usage notes for the adapter are available separately in a support article: Using the Ably Pubnub Protocol Adapter. Please note that this tutorial assumes that you already have Pubnub client libraries set up with Pubnub, and just want to convert it to use Ably.

To take advantage of Ably features not supported by the PubNub client libraries such as connection state recovery you’ll need to fully migrate over to Ably. But in this tutorial, we’ll see how you can get started using the PubNub protocol adapter.

Step 1 – Create your Ably app and API key

To follow this tutorial, you will need an Ably account. Sign up for a free account if you don’t already have one.

Access to the Ably global messaging platform requires an API key for authentication. API keys exist within the context of an Ably application and each application can have multiple API keys so that you can assign different capabilities and manage access to channels and queues.

You can either create a new application for this tutorial, or use an existing one.

To create a new application and generate an API key:

  1. Log in to your Ably account dashboard
  2. Click the “Create New App” button
  3. Give it a name and click “Create app”
  4. Copy your private API key and store it somewhere. You will need it for this tutorial.

To use an existing application and API key:

  1. Select an application from “Your apps” in the dashboard
  2. In the API keys tab, choose an API key to use for this tutorial. The default “Root” API key has full access to capabilities and channels.
  3. Copy the Root API key and store it somewhere. You will need it for 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',
  :origins_pool  => ['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 Ably client libraries can use websockets as a transport (Pubnub can only do long polling), and more efficient because using Ably client libraries avoids the overhead of protocol translation.
  4. Get in touch if you need help