Server-Sent Events with FLASK+Redis using Pub/Sub

Subhajit Dutta
4 min readOct 17, 2021
Could not get anything better for SSE

First thing first — Why should we bother? ( TLDR )

In a typical Rest API, we know, a client sends and request to a backend server and the server responds to that request. Simple.

Now think about a “live cricket score” web app, where you have to notify the client whenever there is a change in the score. Now there can be three popular ways to solve this ( There can few more but let’s not discuss that )…

1. Continuously polling the server

You cannot use this, as the change in the backend data can be at some anonymous time, and keep on hitting backend APIs will be a waste of resources.

2. Websocket

This can be a better solution but we have better than this as well, trust me. Just remember Websockets are Full-Duplex communication where both client and server keep on interchanging data.

3. Pub/Sub ( Push notifications )

This will be better utilisation of resources but end user has to give consent in order to make this work.

4. Server-Sent Events

Finally we are here. Server-sent events (SSE) is a mechanism for sending updates from a server to a client.

It is a server push technology enabling a client to receive automatic updates from a server via an HTTP connection, and describes how servers can initiate data transmission towards clients once an initial client connection has been established.

The fundamental difference with WebSockets is that the communication only goes in one direction. In other words, the client cannot send information to the server

How it works?

SSE can be considered as a one-way publish-subscribe model.
SSE is a mechanism that allows the server to asynchronously push the data to the client once the client-server connection is established. The server can then decide to send data whenever a new “chunk” of data is available. When client-server establishes SSE handshake, the connection is kept open until it is forced to close.

In typical use case, server often exposes an endpoint which returns with "Content-Type: text/event-stream" and required chunk of data.

On the client(Frontend), The server-sent event API is contained in the EventSource interface; to open a connection to the server to begin receiving events from it, create a new EventSource object with the URL of a script that generates the events.

const evtSource = new EventSource("//my-cool-api", { withCredentials: true } );
This is how it looks like in a Chrome browser

Flask + SSE implementation

TLDR, Server-sent events do not work with Flask’s built-in development server, because it handles HTTP requests one at a time. The SSE stream is intended to be an infinite stream of events, so it will never complete. If you try to run this code on with the built-in development server, the server will be unable to take any other requests once you connect to this stream. Instead, you must use a web server with asychronous workers. (Study here)

Prerequisites

You must have Redis installed in order to get this working. Check out the link for help: https://flaviocopes.com/redis-installation/

Let's see some code now. We are going to initialize flask_sse below.

On the frontend,

var sse_url = "http://0.0.0.0:5000/stream?channel=mychannel
var source = new EventSource(sse_url);
source.addEventListener('message', function(event) {
console.log(event.data)
});
source.addEventListener('error', function(event) {
console.log("Error == ", event.data)
});

Now let’s generate an event…

sse.publish({"score": 100}, channel="mychannel")

You can also push an event directly to the redis channel which is used by the SSE library. As flask_sse also uses Redis Pub/Sub internally, it just takes same channel and proper data format to publish an event to Redis Pub/Sub and then subscribe by flask_sse. Code below…

redis_client.publish("mychannel", json.dumps(
{"data": {"score": 100}}))

Use Cases of Server Sent Events

Let’s see the use case with an example — Consider we have a real time graph showing on our web app, one of the possible options is polling where continuously client will poll the server to get new data. Other option would be to use server sent events, which are asynchronous, here the server will send data when updates happen.

Other applications could be

  • Real time stock price analysis system
  • Real time social media feeds
  • Resource monitoring for health, uptime

Try this out, write a project and comment the github url. I’d love to see what challenges you face.

--

--