Real-time web application: What're the different ways to play with live/real data
Real-time web application

Real-time web application: What're the different ways to play with live/real data

Recently I have been curious about the best way to implement a?real-time web application. That is an application containing one or more components that automatically update, in real-time, reacting to some external event. Building a real-time web application is challenging, as we need to know how we will send our latest (real-time) data from server to client more efficient way and with low latency, the reason this research has made me more curious as I was working on a recent project where we need to wait for the background process (having back and forth backend external API calls) to complete/update the status and notify to the user based on the outcome.

There are various techniques to retrieve real-time data from the server:

  • Short/Long polling (client pull)
  • WebSockets (server push)
  • Server-Sent Events (server push)
  • Azure SignalR Service
  • Blazor Server Realtime without SignalR using Singleton

Client pull — client asks the server for updates at certain regular intervals

Server push —?server is proactively pushing updates to the client (reverse of client pull)

Let’s take a simple use case to compare the above technologies and choose the right one.

There are so many use cases that we could think of for real-time web applications and a few of them are here for your reference point.

  • Superstore ordering system
  • Payment processing system
  • Appointment booking system
  • Real-time statistic dashboard i.e forex trading app, Stock Market App, News site, chat application, etc

Polling is a technique by which the client asks the server for new data regularly.

Short polling (client pull)

Short polling?is an AJAX-based timer that calls at fixed delays

The simplest way to get new information from the server is periodic polling. That is, regular requests to the server: “Hello, I’m here, do you have any information for me?”. For example, once every 10 seconds.

That works, but there are downsides:

  1. Messages are passed with a delay of up to 10 seconds (between requests).
  2. Even if there are no messages, the server is bombed with requests every 10 seconds, even if the user switched somewhere else or is asleep. That’s quite a load to handle, speaking performance-wise.

So, if we’re talking about a very small service, the approach may be viable, but generally, it needs improvement.

No alt text provided for this image
Figure 1: Short polling
export default {
  name: 'PollingOutcome'
	data() {
		return {
			polling: null
		}
	},
	methods: {
		async pollData() {
			this.polling = setInterval(() => {
				this.pollingOutcome()
			}, 3000) // polling every 3 secs 
		async pollingOutcome(){
		  this.$store.dispatch('GetEndpoint');
		  if(this.getStatus === 'Done'){
			clearInterval(this.polling); // destroy polling
		  }
		},
		async getRealTimeData()
	    {
		  this.pollData();
	    }
	},
	beforeDestroy() {
		clearInterval(this.polling)
	}
};         

Long polling (client pull)

Long polling is the simplest way of having a persistent connection with the server, that doesn’t use any specific protocol like WebSocket or Server-Sent Events. It is a much better way to poll the server instead of using short polling.

This situation, where the browser has sent a request and keeps a pending connection with the server, is standard for this method. Only when a message is delivered, the connection is closed and re-established.

No alt text provided for this image
Figure 1: Long Polling
No alt text provided for this image
Figure 2: Long Polling

The flow:

  1. A request is sent to the server.
  2. The server doesn’t close the connection until it has a message to send.
  3. When a message appears – the server responds to the request with it.
  4. The browser makes a new request immediately.

If the connection is lost, because of, say, a network error, the browser immediately sends a new request.

Server should be ok with many pending connections?

Long polling is much more resource intensive on servers whereas WebSockets have an extremely lightweight footprint on servers. The maximum number of connections a web application may make is limited by each web browser. This implies that the load time and performance of your application may suffer as a result.

The server architecture must be able to work with many pending connections.

Certain server architectures run one process per connection, resulting in there being as many processes as there are connections, while each process consumes quite a bit of memory. So, too many connections will just consume it all

There are a few more issues to consider:

Headers Overhead

Connection Establishment

Maximal Latency

Performance Degradation

Timeouts

Multiplexing

You can read about more real-world challenges?here.

When to use

Long polling works great in situations when messages are rare.

subscribe: (callback) => {
	    const pollUserEvents = () => {
	        $.ajax({
	            method: 'GET',
	            url: 'https://localhost:8080/githubEvents', 
	            success: (data) => {
	                callback(data) // process the data
	            },
	            complete: () => {
	                pollUserEvents();
	            },
	            timeout: 30000
	        })
	    }
	    pollUserEvents()
	}        

WebSockets (server push)

A WebSocket is a helpful alternative to lengthy/long polling in HTML5. A WebSocket is a technology that allows users to communicate in full-duplex over a single TCP connection. The WebSocket protocol allows for more interaction between a browser and a website, allowing for live content and removing the need for long polling cycles.

No alt text provided for this image
Figure 1: WebSockets

This is ideal for real-time apps since, after the initial HTTP handshake, a single WebSocket connection can handle all of the messages for a single session, without any further handshakes. When the session finishes, the connection should be closed as part of the clean-up.

No alt text provided for this image
Figure 2: WebSockets

  • Uses a custom ws protocol to transport messages, which works at a lower level than HTTP.
  • Connection is two-way, so WebSockets is useful for apps that require data to be read from and written to the server, such as?chat apps?or?multiplayer games.
  • It can be complex to implement WebSocket from the ground up, but there are a wide variety of libraries available to facilitate this.
  • Event-based; no polling is required to retrieve messages, helping to reduce latencies.

Because WebSocket provides a full-duplex, bi-directional communication channel, the server can send messages to the client, and both can send messages at the same time. This makes two-way, multi-user real-time apps such as chat rooms possible and performant. WebSockets can transmit binary data and UTF-8 meaning that apps can support sending plain text and binary formats such as images and video.

$(function () {
	  // if user is running mozilla then use it's built-in WebSocket
	  window.WebSocket = window.WebSocket || window.MozWebSocket;

	  const connection = new WebSocket('ws://localhost:8080/githubEvents');
	  connection.onopen = function () {
	    // connection is opened and ready to use
	  };
	  connection.onerror = function (error) {
	    // an error occurred when sending/receiving data
	  };
	  connection.onmessage = function (message) {
	    try {
	      const githubEvent = JSON.parse(message.data); 
	    } catch (e) {
	      console.log('This doesn\'t look like a valid JSON: '+ message.data);
	      return;
	    }
	    // handle incoming message
	  };
	});        

What is wrong with WebSockets

Two-way channels and low latency are extremely good features. Why bother looking further?

WebSockets have one major drawback:?they do not work on top of HTTP, at least not fully. They require their own TCP connection. They use HTTP only to establish the connection, but then upgrade it to a standalone TCP connection on top of which the WebSocket protocol can be used.

This may not seem a big deal, however, it means that?WebSockets cannot benefit from any HTTP feature but that doesn't mean that you can not enhance further.

  • No support for compression
  • No support for HTTP/2 multiplexing
  • Potential issues with proxies
  • No protection from Cross-Site Hijacking

As mentioned above, there are a number of libraries that are popular WebSockets-based libraries like Socket.IO which solve the Fallback to HTTP and support for reconnection.

Server-Sent Events (server push)

Server-Sent Events?enable the server to send low-latency push events to the client, at any time. They use a very simple protocol that is?part of the HTML Standard?and?supported by every browser.

Unlike WebSockets,?Server-sent Events flow only one way: from the server to the client. This makes them unsuitable for a very specific set of applications, that is, those that require a communication channel that is?both two-way and low latency, like real-time games. However, this trade-off is also their major advantage over WebSockets, because being?one-way,?Server-Sent Events work seamlessly on top of HTTP, without requiring a custom protocol. This gives them automatic access to all of HTTP’s features, such as compression or HTTP/2 multiplexing, making them a very convenient choice for the majority of real-time applications, where the bulk of the data is sent from the server, and where a slight overhead in requests, due to HTTP headers, is acceptable.

The protocol is very simple. It uses the?text/event-stream?Content-Type and messages of the form:

No alt text provided for this image
Figure 1: SSE

In other words. Server-Sent Events (SSE) are based on Server-Sent DOM Events. Browsers can subscribe to a stream of events generated by a server using the EventSource interface, receiving updates whenever a new event occurs. EventSource accepts an HTTP event stream connection from a specific URL and keeps the connection open while retrieving available data. Server-sent events are pushed (rather than pulled, or requested) from a server to a browser.

No alt text provided for this image
Figure 2: SSE

Server-Sent Event is a standard describing how servers can maintain data transmission to clients after an initial client connection has been established. It provides a memory-efficient implementation of XHR streaming. Unlike a raw XHR connection, which buffers the entire received response until the connection drops, an SSE connection can discard processed messages without accumulating all of them in memory.

Summary of key Server-Sent Events Features

  • Uses XHR streaming to transport messages over HTTP.
  • Connection is one-way, so SSEs are useful for apps that only require reading data from the server, such as livestock or news tickers.
  • Less complex to implement SSE-based connections, but not many related libraries are available.
  • Event-based; no polling required to intercept messages. Server-Sent Events are?specified in the HTML specification?and have been supported by all major browsers for a number of years. See the?EventSource browser support table?on MDN for more details.

SERVER-SENT EVENTS ADVANTAGES:

  • Polyfillable:?Server-Sent Events can be poly-filled with JavaScript in browsers that do not support it yet. This is useful for backward compatibility because you can rely on the existing implementation rather than having to write an alternative.
  • Built-in support for reconnection:?Server-Sent Event connections will reestablish a connection after it is lost, meaning less code to write to achieve an essential behavior.
  • No firewall blocking:?SSEs have no trouble with corporate firewalls doing packet inspection, which is important for supporting apps in enterprise settings.

SERVER-SENT EVENTS DISADVANTAGES:

  • Data format limitations.?Server-Sent Events are limited to transporting UTF-8 messages; binary data is not supported.
  • Limited concurrent connections.?You can only have six concurrent open SSE connections per browser at any one time. This can be especially painful when you want to open multiple tabs with SSE connections. See 'Server-Sent Events and browser limits' for more information and workaround suggestions.
  • SSE is mono-directional.?You can only send messages from server to client. While this is useful for creating read-only real-time apps like stock tickers, it is limiting for many other types of real-time apps.

What is the difference between WebSockets and Server-Sent Events?

The following table provides a quick summary of the key differences between WebSockets and Server-Sent Events.

WebSockets

  • Two-way message transmission
  • Supports binary and UTF-8 data transmission
  • Supports a large number of connections per browser
  • Can't be polyfilled using JavaScript; you need to fall back to basic HTTP messages
  • Some enterprise firewalls with packet inspection have trouble dealing with WebSockets

Server-Sent Events

  • One-way message transmission (server to client)
  • Supports UTF-8 data transmission only
  • Supports a limited number of connections per browser (six)
  • Can be polyfilled using JavaScript
  • No blocking by enterprise firewalls

Should I use WebSockets or Server-Sent Events?

Which technology to use depends on your use case. In this section, we will look at suitable use cases for both.

When to use WebSockets

WebSockets are more complex and demanding than SSE and require a bit of developer input up front. For this investment, you gain a full-duplex TCP connection that is useful for a wide range of application scenarios. For example, WebSockets are preferable for use cases such as?multiplayer collaboration?and?chat apps.

Why use Server-Sent Events over WebSockets?

Server-Sent Event is a good?alternative to WebSockets?for simple real-time use cases that only require one-way communication (from server to client).

Ideal use cases of SSE:

  • Stock ticker streaming
  • Twitter feed updating
  • Notifications to browser

Keep in Mind:

  • No binary support
  • Maximum open connections limit


To be continued...

References:

  1. https://www.smashingmagazine.com/2018/02/sse-websockets-data-flow-http2/#comments-sse-websockets-data-flow-http2
  2. https://learn.microsoft.com/en-us/archive/msdn-magazine/2012/may/cutting-edge-understanding-the-power-of-websockets
  3. https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API
  4. https://www.rfc-editor.org/rfc/rfc6202#section-2.2

要查看或添加评论,请登录

Sandeep Rastogi的更多文章

  • Exploring Container Services on AWS: A High-Level Overview

    Exploring Container Services on AWS: A High-Level Overview

    In the dynamic landscape of cloud computing, the need for agility, scalability, and efficiency has led many…

    1 条评论
  • Search as a Service (SaaS) - AWS OpenSearch (formerly AWS ElasticSearch)

    Search as a Service (SaaS) - AWS OpenSearch (formerly AWS ElasticSearch)

    In today's digital age, the ability to quickly and efficiently search and discover information is crucial. Whether…

  • Cron Jobs on AWS

    Cron Jobs on AWS

    Cron jobs, short for "chronos" in Greek, are scheduled tasks that automate repetitive processes and streamline…

  • Azure Service Bus and Azure Storage Queues

    Azure Service Bus and Azure Storage Queues

    In my previous article, I explained the difference between Event and Message, and also reviewed Azure Event Hub and…

  • Azure Event Hub and Azure Event Grid

    Azure Event Hub and Azure Event Grid

    Event vs Message The naming convention sounds the same at first glance but there is a difference. Firstly, Let's…

  • Microsoft Azure Notification Hub

    Microsoft Azure Notification Hub

    Azure Notification Hubs provide an easy-to-use and scaled-out push engine that enables you to send notifications to any…

社区洞察

其他会员也浏览了