Realtime: Pull and Push Models Implementations

Realtime: Pull and Push Models Implementations

In this article we will discuss the different implementations of transferring realtime data from a backend to a client (polling, long polling, web sockets and SSE). All these different implementations are either client pulling data from the backend or the backend pushing data to the client (two different models). Backend and client doesn't have to be typical web application and web server that serves API, this relationship can also exist between two servers, a server and a DB (the server being the client here) etc.

The goal of this article is that you, as the developer of a realtime system, would know what's best for your use case.

I rather start with the simplest model - pull. Within that model, we have two implementations for transferring data between a client and a backend in realtime: polling and long polling.

Polling - this is simply the client asks the backend every x units of time for data. Imagine a chatting system (has to be realtime right?) where you can chat with others in chat rooms. So if you, the user, currently inside a chat room, and this chat system uses polling to transfer data between the client and the backend, that would look like -

Client: Hey backend, does chat 123 has new messages?

Backend: Yep. Here they are [....]

.

.

.

Client: Hey backend, does chat 123 has new messages?

Backend: No

.

.

.

.

Client: Hey backend, does chat 123 has new messages?

Backend: Yep. Here they are [....]

And so on...

As you can imagine, this implementation is rather wasteful, both for client and backend. It would also mean that we wouldn't get our chat messages as they come, but only when the client asks for them. The pro of this implementation is that it's really easy to implement and completely stateless between client and backend. This is classic Request/Response model and using HTTP to implement this is really easy. A better use case for this implementation is when we are building a monitoring system, and checking if our services are alive. In that case, we would set an interval of one minute (or whatever suits you) between each call, and we could monitor our services (literally ping them every now and than). Grafana uses polling to serve its dashboards. Another really famous architecture that uses polling is the event loop inside javascript engine that is basically responsible to decide what should be done next (in that case the backend being the local memory so it is rather cheap).

The next implementation, also a pull model, is Long Polling. In this implementation the client asks for data, and the backend returns answer only when there is data to send. So in the chatting example, that would look like:

Client: Hey backend, does chat 123 has new messages?

Backend: Yep. Here they are [....]

Client: Hey backend, does chat 123 has new messages?

.

.

.

.

.

Backend: Yep. Here they are [....]

This implementation is much better in terms of realtime (the client can get the data as it comes) and it's also less wasteful from both sides. The cons here are that it's a bit harder to implement on the backend side - backend becomes a bit stateful because he needs to save the clients that asked for messages for different chats because the response doesn't come right away. And you also have to worry about setting timeouts and the client needs to remake his request after getting an answer.

*Notice - if using the HTTP protocol from a web browser you would rather use HTTP/2 here and not HTTP/1.1 because as long as the backend didn't return any answer, the connection is open and the browser is limited to six parallel connections at a time. If using HTTP/2, it uses multiplexing which allows multiple requests being made using the same TCP connection.

A big pro of long polling is that it's highly scalable - meaning you can spin up easily multiple backends to handle the requests and load balance between them (have a master slaves architecture, where one master does the writes and reads can be done from everyone) and have an eventually consistent system. A very famous tool that uses long polling is kafka (yes, yes though to us it may seem a push model - behind the scenes the consumer is long polling the broker).

After we have discussed pull model implementations and use cases let's move on to the push model implementations. We are going to discuss two main implementations: Web Sockets and SSE (Server Sent Events). There are more implementations (like amqp invented by rabbitmq, uses TCP as its underlying layer) that we won't cover in this article.

So let's start the push model discussion with Web Sockets. Think of this protocol as an upgraded TCP, which client and backend can transfer packets (with no limit) between them, meaning it allows bi-directional messaging. This sounds great, and web sockets are indeed widely used by popular applications like firebase and whatsapp, but it does come with disadvantages. Web Sockets are really hard to proxy and load balance, because it's statefulness connection between the client and backend. The six connections limit mentioned before does not apply to Web Sockets - it is much higher (255 in chrome, 200 in firefox). A classic use case for Web Sockets would be when a client and a backend communicate a lot in a bi-directional way in order to transfer realtime data - like a chatting app. That would look like:

Client: Backend, let's do Web Sockets on chat room 123

Backend: Sure, I support it.

Client: Hey backend, here's a new message I wrote in chat room 123

Backend: Got it. Also - backend sends to all clients that subscribed to chat room 123 the new message

Last but not least, we will discuss the SSE implementation. Think of this one as a glorified long polling. In this implementation, the client will ask the backend for data (a stream), and the backend will emit events every time new data arrives. The client doesn't need to worry about remaking the requests (as oppose to long polling) because the stream can be endless. Also, if any error occurred in the backend or the connection was dropped, EventSource (the object being used to make an SSE request) automatically retries the same request. It works under the hood with HTTP streams, and as mentioned in long polling, better to use over HTTP/2 (due to six connections limit in browsers). This is classic for use cases where the client needs realtime data that is generated by the backend with little influence by the client. For example, let's say we have an app that monitors the live locations of people in a certain area. So the communication would look like:

Client: Hey backend, please give me the live locations of the all the people in area 123

Backend: {event: message, data: [people locations...]}

Say a person moved in that area

Backend: {event: message, data: [new people locations...]}

SSE cons are that it is currently doesn't support headers - although running on top of HTTP, it uses the EventSource object to open streams which only gets a URL at the moment, so you would have to use query params.

That's it! Hope I shed some light on the different models and implementations to communicate in realtime between a client and a backend.

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

Matan Rabi的更多文章

  • System Design - Simplified

    System Design - Simplified

    The whole System Design topic is so amorphous that reading many articles about it, can result in very little practical…

    3 条评论
  • Sync, Async, multi-threading and multi-processing programming techniques

    Sync, Async, multi-threading and multi-processing programming techniques

    In this article, we will discuss those different methods to execute code, show use cases for each one and discuss the…

  • CI/CD, demonstrated with Docker and Jenkins

    CI/CD, demonstrated with Docker and Jenkins

    CI/CD is a concept in software development, it means Continues Integration, Continues Delivery. Integration: Installing…

  • DB Queries - Index Optimization

    DB Queries - Index Optimization

    In this article, we will discuss the problems that index solves, short brief of how index is implemented, when and when…

    2 条评论
  • Microservices Architecture – In a nutshell

    Microservices Architecture – In a nutshell

    The year is 2015. Netflix, breaks out with its newly software development technique – ‘Microservices’ (effort that…

    6 条评论

社区洞察

其他会员也浏览了