14. SSE

Server-sent events, or SSE, work in a similar way to WebSockets, since they let you send asynchronous messages between the backend and the frontend without making new requests. However, there are 2 notable differences.

How server sent events work

  • The HTTP protocol is used.
  • Information flows in one direction, from the server to the client.

In the following example we can see how a client connects to a source and waits for a change.

const sse = new EventSource("https://ejemplo.com");

sse.addEventListener("message", function(evento) {
    document.querySelector('#contador').textContent = evento.data;
});

Using Node

If you want to create a server that sends requests via SSE, for teaching purposes, you can quickly build a backend with Node. We'll send a counter that increments every second, and serve it at the route http://localhost:3000/eventos.

1- I'll assume your machine already has Node, so just install the minimum dependencies:

npm install express cors

2- Next, a file called index.js with the following content:

const express = require('express');
const cors = require('cors');

// Starts server
run().catch(err => console.log(err));

async function run() {
  const app = express();
  app.use(cors());

  app.get('/eventos/', async function(req, res) {
    res.set({
      'Cache-Control': 'no-cache',
      'Content-Type': 'text/event-stream',
      'Connection': 'keep-alive'
    });
    res.flushHeaders();

    // Tells the client to restart the connection, if lost, every 10s
    res.write('retry: 10000\n\n');
    let count = 0;

    while (true) {
      await new Promise(resolve => setTimeout(resolve, 1000));
      // Increments the counter
      count++;
      // Emits an SSE with a number that increments every second
      res.write(`data: ${count}\n\n`);
    }
  });

  await app.listen(3000);
  console.log('Listening on port 3000');
}

3- Start the server.

node index.js

4- Create an HTML file with the following content and open it with your favorite browser.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
  <div id="contador"></div>
  <script>
    const sse = new EventSource("http://localhost:3000/eventos/");

    sse.addEventListener("message", function(evento) {
       document.querySelector('#contador').textContent = evento.data;
    });
  </script>
</body>
</html>
Activity 1

When the counter is divisible by 10, show a modal with the current amount.

Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python

Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python

The HTML over WebSockets approach simplifies single-page application (SPA) development and lets you bypass learning a JavaScript rendering framework such as React, Vue, or Angular, moving the logic to Python. This web application development book provides you with all the Django tools you need to simplify your developments with real-time results.

Buy the book

Help me keep writing

Every coffee gives me a push toward the next article.

Comments

There are no comments yet.