{{announcement.body}}
{{announcement.title}}

Ably Masterclass, Episode 1 — Building a Realtime Voting App in Less than An Hour

DZone 's Guide to

Ably Masterclass, Episode 1 — Building a Realtime Voting App in Less than An Hour

This masterclass introduces and discusses the importance of realtime streaming applications and demonstrates them by building a live voting app.

· Web Dev Zone ·
Free Resource

It was just a month ago that the idea of hosting a monthly masterclass series surfaced at Ably and yesterday I hosted the first episode where I taught the audience how they can build a realtime voting app in less than an hour.

So, in this post I’m summarizing what happened, along with links to some useful resources to check out.

I’ve hosted the slides online so you can check them out as well!

As this was the first episode of the series I thought it’d be best to start off with an intro to what ‘Realtime’ means and demystify some buzzwords such as Pub/Sub, persistent connections, event-driven systems etc. I’ve explained this below:

A Super Brief Intro to Realtime Concepts

Since the advent of the internet, its participating entities have communicated over the well-known Hypertext Transfer Protocol (HTTP). You have requests and responses and new connection cycles for each request-response style communication. This has worked incredibly well for applications where the primary goal is to fetch some data, send some data, or get some computation done at the server-side.

REST Requests

REST Requests


But the past couple of years have seen data sharing move to a more event-driven approach. This means that the participating entities are interested in being notified of something as soon as it has occurred. This is the kind of communication that is popularly referred to as "real-time." Examples of such applications are live location-tracking apps, chat apps, HQ-style quiz apps, live data streams involving bitcoin prices, stock markets, and news, to name a few.

Realtime streaming examples

Realtime streaming examples



If you think about such applications, the traditional HTTP based communication using REST requests falls short. Needing to set up new connection cycles each time, client-only initiated communications, and not to mention the data overload, leads to a lot of latency - and if there's one major thing to an application being 'realtime', it's that it is capable of communicating with the least possible latency.

So if not HTTP, then perhaps Long Polling? Well, Long Polling has almost the same disadvantages as HTTP-based communication when it comes to realtime apps. Granted, they can keep the connection open until the server has some data to return back in the response but we need something that can enable the server communicate with a client whenever it likes. In other words, a server-initiated communication. So, Long Polling isn't an option, either.

This is where the concept of "real-time subscriptions" comes into play. There are certain realtime protocols such as WebSockets, MQTT, and SSE that allow for push-based communication (as opposed to the pull-based way of getting updates via HTTP). Let's take a quick look at WebSockets:

WebSockets

WebSockets


Communication starts off as an HTTP request but with an additional upgrade header. If the other party is compliant with WebSockets as well, the connection is upgraded, leading to a full-duplex (communication is possible in both directions) and persistent (the connection can stay open for as long as you need) connection. This works perfectly for event-driven applications as any entity wanting to share and update simply pushes data to the other clients and they are instantly notified (latency is of the order of a few milliseconds).

This is how the concept of publishers and subscribers comes into play. Now that it's all a bit more clear, let's get into the app that I built during the webinar. Again, remember, I'm only doing a rapid summary of things I covered in the masterclass here. You should really be looking at the recording for detailed info on realtime concepts as well as the voting app.

Coding the Voting App From Scratch

So the end-result of the app I built looked something like so:

Final application

Final application


As you can see, these are two separate entities or apps, one a voting interface to cast votes using basic HTML buttons, and the other a chart that shows the resulting votes cast for different choices in the form of a chart. And oh did I mention? This chart updates in realtime as new votes get cast by users.

These two apps communicate in realtime via Ably, we use Fusioncharts to conveniently build a chart with our data and this whole app is publicly hosted using Glitch.

Starting with the voting interface app, it's a basic HTML layout, uses bootstrap to look fancy and has a few lines of code to connect to an Ably channel and publish votes as they are being cast. You should check out this directly on GitHub as a blog post is not a good place to host code. But again, just to sum up, the way you initialize Ably, attach to a channel and start publishing data is just a matter of a few lines of code:

Java
 




xxxxxxxxxx
1
10


 
1
        // Init Ably library
2
        var realtime = new Ably.Realtime({ key: '<YOUR-ABLY-API-KEY>' });
3
        // Attach to a channel
4
        var myVotingChannel = realtime.channels.get('voting-channel')
5
        // Publish data on the channel
6
        var castVote = function(choice){
7
            myVotingChannel.publish('vote', choice, (err)=>{
8
                console.log(err);
9
            });
10
        }


Now, on the chart app, it's also a basic HTML layout with a placeholder <div> tag to house the chart that'll appear as the data's coming through. The main things that need to be done in this app are:

  1. Init Ably
  2. Attach to the voting channel
  3. Subscribe to that channel
  4. Pass on the incoming data onto the chart
Java
 




x


 
1
var realtime = new Ably.Realtime({key: '<YOUR-ABLY-API-KEY>'});
2
var myVotingChannel = realtime.channels.get('voting-channel');
3
myVotingChannel.subscribe('vote', (msg)=>{
4
    console.log(msg.data);
5
    // pass this onto the chart
6
    }


And for the chart itself, the main things that need to be done are:

  1. Prepare the data in an array of objects format
  2. Specify the metadata for the chart, like the type, dimensions, captions, axes, etc
  3. Init FusionCharts and render the chart with the below attributes
Java
 




xxxxxxxxxx
1
28


1
 
          
2
// Preparing the chart data
3
const chartData = []
4
 
          
5
// Chart Configuration
6
const chartConfig = {
7
    type: "pie2d",
8
    renderAt: 'chart-container',
9
    id: 'vote-chart',
10
    width: "100%",
11
    height: "400",
12
    dataFormat: "json",
13
    dataSource: {
14
        "chart": {
15
            "caption": "If age is only a state of mind",
16
            "subCaption": "Which category best describes YOUR state of mind right now?",
17
            "theme": "fusion",
18
        },
19
        // Chart Data from Step 2
20
        "data": chartData
21
    }
22
};
23
 
          
24
// Render the chart
25
FusionCharts.ready(function(){
26
    var fusioncharts = new FusionCharts(chartConfig);
27
    fusioncharts.render();
28
});


As mentioned, the code shown here is just a quick example, the full source code for the voting results app can be found in the GitHub repo.

One quick note is that FusionCharts doesn't quite take into consideration that data may change after the chart is rendered, so to enforce this, you'll need a special method they offer called setJSONData(). This basically requires you to specify the dataSource object in the chart config specified above.

Java
 




xxxxxxxxxx
1


 
1
FusionCharts.items['vote-chart'].setJSONData({
2
        "chart": {},
3
        "data": []
4
});


That's basically it!

Useful Resources

  1. GitHub repo with full source code
  2. Presentation slides
  3. Recorded masterclass video
  4. Live demo of the voting interface app
  5. Live demo of the voting results app
  6. Ably Realtime docs
  7. FusionCharts docs

The next one is going to be about IoT, WebHooks, Zapier and other super fun things. You can find all the info about it on the website.

Further Reading

WebSockets vs. Long Polling

Apps Depend on Real-Time Streaming Data, Here's How to Manage Them

Topics:
realtime ,tutorial ,app development ,apps ,webinar

Published at DZone with permission of Michael Ade-Kunle . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}