Options For Building Real-Time Apps

Introduction & History:

The advent of the web and internet technologies such as TCP/IP, DNS, and HTTP protocols have formed the foundation of many of our internet experiences today. With the rising popularity of JavaScript DOM and XMLHTTPRequest & AJAX, web pages have become more dynamic than ever before as the browser client can asynchronously fetch data from a server all without affecting the UI. However, it wasn’t until the last decade that the challenge for more intense real-time web applications including live-chatting, geolocation tracking, and massively multiplayer online games (MMOG) was resolved.

An Example of MMOG: Warcraft

Polling:

To initially address the challenge of real-time applications, polling was first proposed with two general types: short and long polling. Short polling occurs when a client calls a server at regular intervals, pulling new updates on each request if available. The inefficiency of this approach is that repeated requests to a server waste a tremendous amount of resources. The HTTP request headers must be parsed by the server every time and the server often responds with no data at all. The connection must then be closed each time with all resources cleaned up.

A more efficient alternative is long polling. Rather than the client repeating requests one after another, the client sends a request to the server and the server waits and sends data back as soon as new data becomes available. If no new data is immediately available, the server will wait as long as possible until a timeout. Once the client receives a response from the server (either with or without data), it will then attempt to immediately reconnect with a new request.

Long Polling Model

While polling simulates a real-time experience, it is only a workaround based on AJAX calls. A client can proactively request and receive data from a server: client pull. However, there is no direct mechanism for the server to proactively communicate with the client: server push. On top of this, polling also presents numerous problems including headers overhead, latency, multiplexing, and connection timeouts. Reliable message ordering is often a problem when the same client issues multiple HTTP requests for the same server resource.

WebSockets:

To eliminate some of those problems, a server-push approach was proposed with the birth of WebSockets, which can be described as a thin transport layer over the TCP/IP stack layer. It facilitates persistent, full-duplex (bidirectional) communication over a single TCP connection. Unlike polling, the client can receive event-driven responses without pulling data from the server.

As an evolution of the HTTP protocols, WebSockets were designed to be easily compatible with the HTTP protocols themselves. As stated in the RFC 6455, WebSockets were “designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries’’.

To convert into a WebSocket connection, a new handshake must be established. The client needs to first signal a change in the transport protocol by including a connection field with the value “upgrade” in the request header. Once the server recognizes WebSocket as the value of the upgrade header, the handshake process has begun. The server must then process the handshake and agree to a specific subprotocol. To establish a connection, it must also respond with an upgrade acceptance. Once the client receives a successful handshake request, the WebSocket connection will officially commence. Both the client and server can now send messages to each other!! When it comes time to say goodbye, the connection can be closed by either side.

WebSocket Model

WebSocket Libraries:

To utilize the power of WebSockets, a large number of WebSocket libraries are available for use. Some of the popular open-source libraries are ws, socket.io, and μWS. Ws is a no-frills library designed mostly for implementing the protocol itself. As stated in the ws documentation, it is a “simple to use, blazing-fast, and thoroughly tested WebSocket client and server implementation” with Node.js. However, additional tasks such as pub & sub have to be managed externally.

As an alternative to ws, µWebSockets is arguably one of the fastest WebSocket servers backed by companies including BitMEX and Coinbase. The μWS documentation states that it is “a simple to use yet thoroughly optimized, standards-compliant and secure implementation of WebSockets”. It is also used under the hood by another WebSocket library: SocketCluster.

On a small scale, these open-source libraries for self-hosting are certainly viable options. However, as the application and user base grow in size, a paid hosted solution such as Pusher or PubNub would be necessary to deploy and scale. In fact, the Pusher library claims to “scale billions of messages and connections” with a 99.997% API uptime. To understand how this works, many of those hosted cloud solutions rely on a publish and subscribe architecture. As an example using the Pusher library, a pusher channel allows an application to subscribe to a channel of interest. When a system broadcasts an update to the channel, all the channel subscribers will promptly receive the update. When sensitive data are a concern, private channels can be set up to restrict subscribers with permission.

Pub & Sub Architecture

Server-Sent Events:

While WebSockets are certainly advanced and powerful technologies, some of the drawbacks include the complication of the proxy servers, number of connections, and load balancing. It turns out another server-push solution exists and also based on this idea of the publish and subscribe model. Server-sent events (SSE) are a unidirectional pub & sub mechanism from the server to the client. It allows the server to asynchronously push data to the client upon a connection and the browser client can receive a stream of events from the server.

A standard JS API named EventSource is supported by most modern browsers (including Chrome and Safari) and used to connect to a server over HTTP. To respond to a client request, the server needs to specify the content type as “text/event stream” with a correct message format consisting of key/value pairs including an id, event type, and data. On the client-side, event handlers can be set up to listen for incoming events. Unlike polling, a persistent connection is established until the client or the server closes it.

Server-Sent Event Model

SSE also presents a few unique features. A client can send a unique id with data to the server. When the client reconnects after dropping, it can send the id of the last received event to the server. The server can then see the number of missed messages and send them back. The server can also tell the client the length of wait time before attempting to reconnect. Another unique feature is that a persistent connection can be established with out-of-the-box multiplexing over HTTP/2. Since this is a unidirectional mechanism, it also provides a simpler implementation and greater efficiency compared to the bidirectional WebSockets.

Conclusion:

Now, after this long-winded discussion, which mechanism should you choose for your next real-time application? Polling or WebSockets or SSE?

The answer is that it depends. It is increasingly rare to use polling by itself especially with its long list of drawbacks from latency to message ordering. However, it is still used as a fallback transport mechanism in some instances. Server-sent events are often useful in applications where the main data flow is from server to client. Some examples are dashboards, real-time charts, and news feeds. However, for intense live applications such as MMOG and social media messaging, a large number of messages need to be generated from both sides. Thus, WebSockets and a bidirectional publish and subscribe architecture will be a much more feasible solution.

To learn more about polling, WebSockets, SSE, or MMOG, the references below are some interesting resources to dig into:

Thank you so much for reading and hope you enjoyed this overview of the real-time application options. You can find me on LinkedIn if you want to chat with me. Have a great day!!

--

--

Developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store