Tutorials

Publish & Subscribe Tutorial

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

As you can publish a message to any channel, channels provide a means for you to filter data by topic or enforce access control for your subscribers. Only subscribers for those channels will receive those messages.

Messages published can contain string, JSON object, JSON array or binary data payloads.

Publishing and subscribing for messages on channels with our channel API is trivial. Let’s get started.

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 – Install AblyStep 2 – Setup an Xcode project and install AblyStep 2 – Set up environment and install Ably

To start using Ably in your JRE application, you need to include the Ably Client library. We recommend that you include the latest client library via Gradle in your project’s gradle.build file.

apply plugin: 'application'
mainClassName = 'io.ably.tutorial.Example'

repositories {
  jcenter()
}

dependencies {
    compile 'io.ably:ably-java:1.0.0'
}

In the above example a specific version of the library is referenced, however we recommend you check which is the latest stable version and always use that. Follow link to get the latest stable release for Java.

After you add necessary dependencies, you can import AblyRealtime class into your code and initialize it.

import io.ably.lib.realtime.AblyRealtime;

public class Example {
  private final static String API_KEY = "INSERT-YOUR-API-KEY-HERE";

  public static void main(String[] args) {
      try {
          initAbly();
      } catch (AblyException e) {
          e.printStackTrace();
      }
  }

  private static void initAbly() throws AblyException {
      AblyRealtime ablyRealtime = new AblyRealtime(API_KEY);
  }
}

See this step in Github

To build your own Android Project, please visit Android Developers website and get familiar with steps necessary to set up your own application.
To start using Ably in your Android app, you need to include the Ably Client library. We recommend that you include the latest client library via Gradle in your module-level gradle.build file.

apply plugin: 'com.android.application'
...
dependencies {
    ...
    compile 'io.ably:ably-android:1.0.0'
}

In the above example a specific version of the library is referenced, however we recommend you check which is the latest stable version and always use that. Follow link to get the latest stable release for Android.

After you add necessary dependencies, you can import AblyRest class into your code and initialize it.

import io.ably.lib.realtime.AblyRealtime;

public class ExampleActivity extends AppCompatActivity {
  private final static String API_KEY = "INSERT-YOUR-API-KEY-HERE";

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_example);
      try {
          initAbly();
      } catch (AblyException e) {
          e.printStackTrace();
      }
  }

  private void initAbly() throws AblyException {
      AblyRealtime realtime = new AblyRealtime(API_KEY);
  }
}

See this step in Github

To start using Ably in your web app, you first need to include the Ably library. We recommend that you include the latest client library from our CDN using a simple <script> tag. The client library must be instanced with the API key you copied in Step 1. Note in production we recommend you always use the token authentication scheme for browser clients, however in this example we use an API key for simplicity.

Include the code below just before your closing your HTML </html> tag.

<script src="https://cdn.ably.io/lib/ably.min-1.js"></script>

<script type="text/javascript">
  var realtime = new Ably.Realtime(apiKey);
</script>

See this step in Github

To start using Ably you first need to install the NPM module. The NPM module can be installed as follows:

npm install ably

The client library must be instanced with the API key you copied in Step 1. API keys used with basic authentication for your own servers is generally preferred, however clients running on insecure devices should always use the token authentication scheme instead. In this example, we use an API key for simplicity.

Add the following to a file named example.js to instance the Ably library inside your Node.js server:

var Ably = require("ably");
var realtime = new Ably.Realtime({ key: apiKey });

See this step in Github

To start using Ably you first need to install the Ably RubyGem. The RubyGem can be installed as follows:

gem install ably

Or if using bundler, simply add the following to your Gemfile and run bundle install:

gem 'ably'

The client library must be instanced with the API key you copied in Step 1. API keys used with basic authentication for your own servers is generally preferred, however clients running on insecure devices should always use the token authentication scheme instead. In this example, we use an API key for simplicity.

The Ruby realtime library uses EventMachine to run the client library within an asynchronous event loop. However, typically when using Ruby on servers, most developers use the synchronous REST client library API. As this turorial needs realtime access to subscribe to messages, it uses the Ruby realtime library.

Add the following to a file named example.rb to instance the Ably library inside an EventMachine reactor:

require 'ably'
EventMachine.run do
  ably = Ably::Realtime.new(key: api_key)
end

See this step in Github

To start using Ably you first need to install composer package on packagist into your composer.

composer require ably/ably-php --update-no-dev

The client library must be instanced with the API key you copied in Step 1. API keys used with basic authentication for your own servers is generally preferred, however clients running on insecure devices should always use the token authentication scheme instead. In this example, we use an API key for simplicity.

PHP Client library doesn’t provide Realtime API support, so we’ll create a web app that uses Javascript on the client-side (browser) to demonstrate a server publishing messages to realtime Javascript clients.

Javascript will handle subscribing to messages, while PHP will be responsible for publishing messages.

First let’s create ably.php where we will store Ably library and Api key

<?php
require_once 'vendor/autoload.php';
$apikey = '{{ApiKey}}';
$ably   = new \Ably\AblyRest($apikey);

Next step is to create frontend of our app, and set up Javascript library. create index.php file with code:

<?php
require_once 'ably.php';
?>
<html>
  <head>
    <script src="https://cdn.ably.io/lib/ably.min-1.js" type="text/javascript"></script>
  </head>
  <body>
    <h1>Publish &amp; Subscribe sample</h1>
  </body>
  <script type="text/javascript">
    /* Set up a Realtime client which will subscribe to the 'sport' channel*/
    var realtime = new Ably.Realtime('<?= $apikey?>');
  </script>
</html>

If you would like to try running the server now, you can do so with php -S 0.0.0.0:8000. Once running, open your browser to http://localhost:8000/ and you should see “Publish & Subscribe sample”.

See this step in Github

To start using Ably you first need to install The REST library for Python, it’s hosted on Github and is published on PyPI and can be installed as follows:

pip install ably

The client library must be instanced with the API key you copied in Step 1. API keys used with basic authentication for your own servers is generally preferred, however clients running on insecure devices should always use the token authentication scheme instead. In this example, we use an API key for simplicity.

Python Client library doesn’t provide Realtime API support, so we’ll create a web app that uses Javascript on the client-side (browser) to demonstrate a server publishing messages to realtime Javascript clients.

Javascript will handle subscribing to messages, while Python will be responsible for publishing messages.

web.py is a simple web framework for Python. Django is arguably more popular as a web server framework, however for the purposes of this tutorial it is overkill.

Let’s get going with a simple web.py web server now. Install web.py using pip:

pip install web.py

Now set up a vanilla web.py server in server.py:

from __future__ import unicode_literals
from ably import AblyRest
import web

apiKey = '{{ApiKey}}'
client = AblyRest(apiKey)

render = web.template.render('templates/')

class index:
    def GET(self):
        return render.index(apiKey)

urls = (
    '/', index
)

app = web.application(urls, globals())

if __name__ == "__main__":
    app.run()

In web.py each resource is mapped to a class, which in turn takes action depending on HTTP method used. In this case it’s main domain '/', that will be handled by index class, and it will support HTTP GET.

We’ve used web.py template system to easily pass apiKey to Javascript library, let’s create index.html in templates directory:

$def with (apiKey)
<html>
  <head>
    <script src="https://cdn.ably.io/lib/ably.min-1.js" type="text/javascript"></script>
  </head>
  <body>
    <h1>Publish &amp; Subscribe sample</h1>
  </body>
  <script type="text/javascript">
    /* Set up a Realtime client which will subscribe to the 'sport' channel*/
    var realtime = new Ably.Realtime('$apiKey');
  </script>
</html>

Note on string encodings

Since Ably supports both string and binary payloads, to avoid ambiguity, we recommend that strings passed to the library for publishing to Ably (eg as an event name or payload data) should be unicode strings. In Python 3 this is the normal string type, but in Python 2 it is not, so we suggest you prefix string literals with u prefix (eg u'eventname' – or alternatively, use from __future__ import unicode_literals, which will make this automatic), and to explicitly decode any user input (eg raw_input().decode(sys.stdin.encoding).

If you would like to try running the server now, you can do so with python server.py. Once running, open your browser to http://localhost:8080/ and you should see the text “Publish & Subscribe sample”. If you would like to change port, on which your site will be available, simply add it after command ieg. python server.py 1234 for port 1234.

See this step in Github

We will start by creating an Xcode project for this tutorial. To build your own Xcode Project in Swift visit Apple developer website and get familiar with steps necessary to setup your own application.
When you setup your application delete the default ViewController.swift add new File → New → File… and choose Cocoa Touch Class.

Create new Cocoa Touch Class

Name your new class “ExampleViewController” and choose Swift as language:

Name new Cocoa Touch Class

After that navigate to Main.storyboard in your project, click on the ViewController that has already been added by default during project creation and from the Utilities that are located on the right choose Identity Inspector. Find the field labeled “Class” and select “ExampleViewController”.

Interface design

See this step in Github

To start using Ably you first need to install the Ably pod via CocoaPods. You need to add a Podfile to your project directory:

touch Podfile

Then add this line to your application’s Podfile:

pod 'Ably'

Install it with:

pod install

To learn more about using CocoaPods in your project visit official CocoaPods guide.

Then in your files in which you will be using Ably import:

import Ably

To connect to Ably, you need to instance the client library with the API key you copied in Step 1. API keys used with basic authentication for your own servers is generally preferred, however clients running on insecure devices should always use the token authentication scheme instead. In this example, we use an API key for simplicity.

Add the following to the file in which you imported the Ably library:

let API_KEY = "INSERT-YOUR-API-KEY-HERE"
let client = ARTRealtime(key: API_KEY)

See this step in Github

Step 3 – Subscribe to messages

Now that the library is installed, you can subscribe to messages published on channels. Every app can have an arbitrary number of channels that should be used to filter the messages received by subscribing clients. For example, if building a news feed, you may want one channel for politics named “politics”, and another for sport named “sport”. A user interested in “sport” can subscribe to the “sport” channel to receive updates. If that user is not subscribed to the “politics” channel, then “politics” updates will not be delivered to that user.

Channel channel = realtime.channels.get("sport");
channel.subscribe(new Channel.MessageListener() {
    @Override
    public void onMessage(Message messages) {
        System.out.println("Message received: " + messages.data);
    }
});

See this step in Github

Channel channel = realtime.channels.get("sport");
channel.subscribe(new Channel.MessageListener() {
    @Override
    public void onMessage(Message messages) {
        Toast.makeText(getBaseContext(), "Message received: "
              + messages.data, Toast.LENGTH_SHORT).show();
    }
});

See this step in Github

var channel = realtime.channels.get("sport");
channel.subscribe(function(msg) {
  alert("Received: " + JSON.stringify(msg.data));
});

See this step in Github

var channel = realtime.channels.get("sport");
channel.subscribe(function(msg) {
  console.log("Received: " + JSON.stringify(msg.data));
});

See this step in Github

channel = ably.channels.get('sport')
channel.subscribe do |msg|
  puts "Received: #{msg.data}"
end

See this step in Github

Update index.php and add code below before </script> tag:

var channel = realtime.channels.get("sport");
channel.subscribe(function(msg) {
  alert("Received: " + msg.data);
});

See this step in Github

Update index.html and add code below before </script> tag:

var channel = realtime.channels.get("sport");
channel.subscribe(function(msg) {
  alert("Received: " + msg.data);
});

See this step in Github

If you have not previously had experience building a basic user interface in Xcode, please refer to Apple developer guide on how to build a simple UI and also learn more about adding IBOutlets and IBActions.
To be able to subscribe to a channel and send some initial messages, we will add a listener for new messages and add a button that publishes a message. Go to your ExampleViewController and add a UIButton from Object library. Name the action “subscribeAction”.

Binding UI objects

In a similar fashion add two UILabels and connect one of them so that it will show the last message received. Name it “receivedMessageText”.
Your ExampleViewController should look similar to this view:

Binding UI objects

Add this code to previously added IBAction:

let channel = client.channels.get("sport")
self.receivedMessageText.text = ""

channel.subscribe { message in
    self.receivedMessageText.text = "\(message.timestamp) \(message.data)"
  }
}

See this step in Github

Step 4 – Publishing a message

Publishing a message on a channel ensures that any number of subscribers on that channel receive the message in real time. To publish a message on the “sports” channel we simply call the publish method on the channel, specify an optional message event name, and provide the payload as the second argument.

Channel channel = realtime.channels.get("sport");
channel.publish("update", "{ \"team\": \"Man United\" }", new CompletionListener() {
    @Override
    public void onSuccess() {
        System.out.println("Message sent");
    }

    @Override
    public void onError(ErrorInfo reason) {
        System.out.println("Message not sent, error occurred: "
              + reason.message);
    }
});

See this step in Github

Channel channel = realtime.channels.get("sport");
channel.publish("update", "{ \"team\": \"Man United\" }", new CompletionListener() {
    @Override
    public void onSuccess() {
        Toast.makeText(getBaseContext(), "Message sent",
        Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(ErrorInfo reason) {
        Toast.makeText(getBaseContext(), "Message not sent, error occurred: "
              + reason.message, Toast.LENGTH_SHORT).make();
    }
});

See this step in Github

var channel = realtime.channels.get("sport");
channel.publish("update", { "team": "Man United" });

See this step in Github

var channel = realtime.channels.get("sport");
channel.publish("update", { "team": "Man United" });

See this step in Github

channel = ably.channels.get('sport')
channel.publish 'update', 'team' => 'Man United'

See this step in Github

Create publish.php file which will be responsible for publishing messages:

<?php
require_once 'ably.php';
if (isset($_POST['message']) && !empty($_POST['message'])) {
    $channel = $ably->channels->get('sport');
    $channel->publish('update', $_POST['message']);
}
?>
<html>
  <body>
    <h1>Input message</h1>
    <form method="post">
      <input type="text" name="message">
      <input type="submit" value="Publish!">
    </form>
  </body>
</html>

And to simplify it even further, let’s add an iframe so that we can publish messages from the same browser window. Add code below just after the <h1>Publish & Subscribe sample</h1>:

<iframe src="publish.php"></iframe>

If you would like to try running the server now, you can do so with php -S 0.0.0.0:8000. Once running, open your browser to http://localhost:8000/ and you should see “Publish & Subscribe sample” and box with “input message”, try it out.

See this step in Github

Let’s create resource for /publish, it will serve as message publisher:

class publish:
    def GET(self):
        return render.publish()

    def POST(self):
        message = web.input().get('message')
        if message is not None:
            channel = client.channels.get('sport')
            channel.publish('update', message)
        raise web.seeother('/publish')

And create publish.html in templates directory with message form:

<html>
  <body>
    <h1>Input message</h1>
    <form method="post">
      <input type="text" name="message">
      <input type="submit" value="Publish!">
    </form>
  </body>
</html>

And to simplify it even further, let’s add an iframe so that we can publish messages from the same browser window. Add code below to index.html, just after the <h1>Publish & Subscribe sample</h1>:

<iframe src="/publish"></iframe>

Let’s update urls:

urls = (
    '/', index,
    '/publish', publish
)

If you would like to try running the server now, you can do so with python server.py. Once running, open your browser to http://localhost:8080/ and you should see the text “Publish & Subscribe sample” and box with “input message”, try it out.

See this step in Github

In this step add another UIButton and bind it to action named “publishAction”. Also, add one more UILabel and an UITextField – bind it in your code as “messageText” . Thanks to that users will be able to write their own messages.
Your view should now look like this:

Binding UI objects

You can also check if an error occurred while sending the message.
Add this code to previously added IBAction:

channel.publish("update", data: messageText.text) { error in
  guard error == nil else {
    return self.showAlert("Error", message:
                          "There was an error while sending the message. \(error)")
  }
}

See this step in Github

We’re done, it’s that simple. We have now shown you how to subscribe to messages on a channel, and then publish messages on a channel. To see this in action, try out the live demo below.

Live demo

Open this demo in a new browser window to see publish & subscribe in action. Alternatively, scan the QR code to see the published message delivered in real time.

Message:

Download tutorial source code

The complete source code for each step of this tutorial 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 publish-subscribe-java

Then you can run project inside your console. Be sure to switch into project’s directory and then use these commands in your terminal:

./gradlew assemble
./gradlew run

Don’t forget to replace your ExampleActivity#API_KEY field with Ably API key.

The complete source code for each step of this tutorial 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 history-android

And then run the demo on your Android device. Check Android Developers website if you are not familiar on how to run an Android Project. Don’t forget to replace your ExampleActivity#API_KEY field with Ably API key.

The complete source code for each step of this tutorial 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 publish-subscribe-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 for each step of this tutorial 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 publish-subscribe-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 for each step of this tutorial 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 publish-subscribe-ruby

And then run the demo locally by adding your Ably API key to example.rb and running the demo bundle exec ruby example.rb

The complete source code for each step of this tutorial 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 publish-subscribe-php

And then run the demo locally by adding your Ably API key to ably.php, install composer dependencies with:

composer install

and run the web server php -S 0.0.0.0:8000.

The complete source code for each step of this tutorial 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 publish-subscribe-swift

In the project directory simply run:

pod install

Open example.xcworkspace and build the demo on your preferred iPhone simulator or device. Don’t forget to replace your ExampleViewController#API_KEY field by adding your Ably API key to ExampleViewController.swift.

The complete source code for each step of this tutorial 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 publish-subscribe-python

And then run the demo locally by adding your Ably API key to server.py, install the required libraries:

pip install ably web.py

and run the web server python server.py.

Next steps

1. If you would like to find out more about how channels, publishing and subscribing works, see the Realtime channels & messages documentation
2. Learn more about Ably features by stepping through our other Ably tutorials
3. Gain a good technical overview of how the Ably realtime platform works
4. Get in touch if you need help