HQ style apps have gained popularity since their release. Here’s how you can build your own HQ style applications with Ably.
In 2017, a live quiz game called HQ Trivia was released, which later went on to become quite popular. It’s a TV game show, playable via a smartphone app that they offer. The idea is that a live TV show airs at a particular time while participants can play the live game for free using their smartphones. Participants have 10 seconds to try their luck, on each question asked.
In such a scenario, speed and latency play huge roles. The app rewards winners with great amounts of money, hence, the tech behind the app cannot afford to go wrong. It gives quite a unique experience to the users. This design pattern aims at explaining how one can build apps like this themselves, using Ably’s realtime platform.
Ably deals with messages in realtime using named channels. For an HQ style app, we will require realtime messaging between the client and the server with minimal latencies. The questions could be sent from the server in the form of a video or just text data for the purpose of this design pattern. The timer is to be maintained by the server as well so that at any point during the game, the server remains to be the single source of truth, thus not letting client’s network issues, if any, affect the realtime game flow.
However, this timer is to be displayed by the client devices for their users (players), hence once again, this requires realtime communication between the server and all of the client devices.
Furthermore, assuming that the game can only start when at least two participants competing against each other are present, the server will need to be aware of the presence events published by clients whenever they enter or leave.
Hence, let’s consider three channels to solve all of the above (of course, the actual number of channels depends on your particular use case). The illustration below gives a broad view of the data flow between players and the server for an app such as HQ trivia when implemented using Ably.
Assuming the number of clients/players for such an application is generally high, we group them into clusters based on their geographical location. Hence, we’d have three channels per cluster. For a dummy cluster ‘x’, let’s name the three channels as below:
Note that the arrows in the illustration above depict the direction of flow of data in these channels.
The broadcast channel can be used by the server to broadcast data simultaneously to all of the players in each cluster. This data could be the questions, correct answers to previously asked questions, timer data, etc. Basically, everything that needs to be sent to all clients alike. All the clients subscribe to the broadcast channel, but they only have subscribe permission, no publish permissions.
Next, the presence channel can be used by the clients to send their presence events to the server. In turn, the server can subscribe to this channel to be notified of this info whenever a presence event occurs. Everyone will have presence permissions on the presence channel, but not subscribe permission. This means you have the ability to query the presence on a channel or subscribe to presence events from your server, but the clients themselves won’t be able to inspect/subscribe to this channel. This avoids the classic n-squared problem i.e. 10k people entering and subscribing to 10k ‘presence-enter’ events would result in 100m messages. However, 10k people entering, generating 10k presence events only for your server results in just 20k messages.
The final one is the publish channel. This can be used by the clients in a particular cluster to publish their data to the server. This data could be their answers to each of the questions, or any other data. Everyone has publish permissions to this channel, but no subscribe rights. This publish channel can be set up to use the Ably Integrations service, so you get a buffer/ shock absorber to cope with a high volume of incoming messages. Ably Integrations is a scalable service that lets you implement load balancing on your servers, trigger events or serverless functions in realtime, and even stream data in realtime to other third-party streaming services.
Ably ensures that messages are delivered to persistently connected subscribers on a channel in the order they were published on that channel by any other Ably client when using one of the realtime libraries. Read more about it in this support article.
Every event from a user, such as entering, publishing a chat message, playing the game in some way, does not necessarily result in a message to all. You would in your server perform aggregation, filtering, and rate limiting.
This ensures that your server has full control over data rate (for instance <5hz) as well as the volume of messages and you can elect to filter as you see fit.
If the cluster sizes turn out to be slightly larger or slightly smaller that’s not really an issue, so long as the clusters are kept at their target sizes.
You have a reliable way to consume data from clients with a shock absorber (the queue), as well as being able to simplify how you process data using workers.
You can ensure you have a constant amount of data published and received regardless of cluster size or activity. Clients won’t become “overloaded” with too much data, potentially that you don’t have control over.
To get you started quickly, we’ve made a sample trivia quiz app with a static set of textual questions with 10 seconds to answer each of them. You can have at most two players for this sample quiz application. Download it from GitHub. You’ll find usage instructions in the README file.