Un graphique mis à jour avec les server-sent events


Aujourd’hui, on va parler des Server-sent events, une technologie permettant de recevoir des messages de la part du serveur.

Le code utilisé est disponible ici :

github generous-folks/demo-dashboard-server-sent-events no-readme

Nous allons découvrir ce que sont les SSE en construisant un graphique mis à jour toutes les secondes.

demo-gif

Fonctionnement

Les SSE fonctionnent de la manière suivante :

  1. Le client demande au serveur d’écouter une route
  2. Le serveur répond qu’il est d’accord pour que le client écoute
  3. Lorsque le serveur le souhaite il envoie des informations au client. Ce dernier reçoit un message qu’il peut traiter comme il le souhaite.
  4. Lorsque l’on ne veut plus recevoir de données le client ou le serveur peuvent interrompre la connexion

schema

Support navigateur

browser-support

Est-il vraiment nécessaire que je parle du navigateur dont on ne doit pas prononcer le nom ?

Quoi qu’il en soit, on peut utiliser un polyfill en cas de besoin.

Code

// server.js

const http = require("http");
const PORT = 5000;

http
  .createServer((req, res) => {
    /* Il est nécessaire d'indiquer au navigateur qu'il va
    recevoir des données de type "text/event-stream" */
    res.writeHead(200, {
      "Content-Type": "text/event-stream",
      "Access-Control-Allow-Origin": "*",
    });

    setInterval(() => {
      const data = {
        value: Math.round(Math.random() * 100),
      };

      /* Les données envoyées doivent suivre un format précis.
      Une chaine de caractères étant "data: mydata", suivi d'un "\n\n".
      Si vous voulez transmettre du JSON il faudra le transformer en
      chaine de caractère comme ci-dessous. */
      res.write(`data: ${JSON.stringify(data)}`);
      res.write("\n\n");
    }, 1000);
  })
  .listen(PORT, () => console.log(`http://localhost:${PORT}`));
// client.js

import c3 from "c3";

/* L'objet EventSource nous permet d'écouter les événements
envoyés depuis le serveur. On l'instancie en lui passant l'URL
d'où proviendront les événements */
const evtSource = new EventSource("http://localhost:5000");

// Initialisation du graphique
const data = [30, 20, 10, 40, 15, 25];
const chart = c3.generate({
  bindto: "#chart",
  data: {
    type: "area",
    columns: [["Random", ...data]],
  },
  bar: {},
  axis: {
    y: {
      max: 200,
      min: 0,
    },
  },
});

/* On effectue un traitement uniquementlorsque
le serveur décide d'envoyer un message */
evtSource.onmessage = function (e) {
  /* Le code ci-dessous est lié à C3.js, mais concrètement,
  on souhaite afficher maximum 10 valeurs sur ce graphique */
  if (data.length === 10) data.shift();

  data.push(JSON.parse(e.data).value);

  chart.load({
    columns: [["Random", ...data]],
  });
};

/* En plus des messages, il est possible d'écouter lorsque
la communication commence et lorsqu'il y a une erreur */
evtSource.onopen = function () {
  console.log("Ah bogaaaas");
};

evtSource.onerror = function () {
  // Je suis certain que vous aussi vous débugguez comme ça
  console.error("Et merde !");
};

Websocket en moins bien ?

C’est pas moins bien, c’est différent !

Avantage des SSE sur les Websockets:

  • Transport via HTTP plutôt que part un protocole spécifique
  • Compatibilité avec les vieux navigateurs grâce aux polyfill
  • Reprise de connexion native
  • Pas de problèmes avec les pare-feux d’entreprises

Avantages des Websockets sur les SSE:

  • Communication bi-directionnelle
  • Supporte le transfert de données binaires
  • ”Pas de limites” de connexions

Sur ce dernier point, il faut savoir que l’on peut avoir maximum 6 connexions ouvertes par navigateur concernant les SSE.

Conclusion

Les SSE font parti de ces technologies dont on entend peu parler. Pourtant, ils sont peu coûteux à mettre en place, 1 header, 1 format de données et le tour est joué.

En terme de cas d’utilisation, les notifications, un flux d’information ou encore la gestion de stock sont parfaitement envisageables.

Les usages possibles sont multiples, mais il faut garder à l’esprit les limitations d’une telle technologie. 6 connexions par navigateur et pas de transfert de données binaires.

Websocket ou SSE, maintenant vous avez le choix pour votre communication serveur → client

Merci de m’avoir lu.

Liens