Server Sent Events

Par Jean-François GAZET le 6 juin 2015

Sur votre site web, lorsque vous avez un long traitement à effectuer côté serveur, il peut s’avérer utile d’afficher l’état d’avancement en temps réel sur une page web. Il existe une API HTTP nommée Server-Sent-Events (SSE). Elle permet de recevoir des notifications push depuis le serveur. Vous pouvez donc l’utiliser avec du PHP, ASP ou autre, du côté serveur, et côté client : du Javascript et du HTML5 dans le navigateur.

Démonstration

Voici une démonstration de ce qu’il est possible de faire. Dans l’exemple ci-dessous, la page que vous êtes en train de lire appelle le script demo-sse.php dont le code est donné plus bas. Celui-ci a une lourde tâche à effectuer : compter chaque seconde, jusqu’à 15, et nous informer de son avancement :

Exemples d’utilisation

Ce principe, qui permet de mettre à jour des informations sur une page web sans la recharger peut être utilisé par exemple pour :

  • afficher un graphique en temps réel (état des stocks, infos sur l’état d’un serveur…)
  • effectuer un traitement particulier sur le serveur et informer de l’avancement (génération de PDF…)
  • barre de progression…

Comment ça marche ?

Côté serveur

Le script envoie les messages avec le type MIME text/event-stream. On peut envoyer un flux de données précédées de data:. Elles se terminent par un retour à la ligne.

data: Premier message

data: Deuxième message, 
data: celui-ci contient deux lignes

data: Troisième message

On peut précéder ces messages d’une mention qui permettra par exemple d’identifier la donnée qui suit :

event: showStatus
data: 5

event: nom
data: Smith

event: prenom
data: John

Voici le code du script PHP de la démo ci-dessus :

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); 

for($i=1;$i<=15;$i++) { // on compte jusqu'à 15
    sleep(1); // pause d'une seconde
    send('showStatus',$i); // envoie le chiffre avec la mention 'showStatus'
    }
send('close','null'); // stop l'écoute du javascript
    
function send($event,$data) {
    echo str_repeat(' ',1024*64)."\n";
    echo 'event: '.$event."\n".'data: '.$data."\n\n";
    @ob_flush();
    flush();
    }    
?>

Côté client

Dans la page HTML, on cré en Javascript un objet EventSource, et on définit les tâches à effectuer selon les informations attendues.

<div id="divInfo"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
if(typeof(EventSource) == "undefined") {
    $("#divInfo").append("Navigateur non supporté");
    throw '';
    }
var source = new EventSource('demo-sse.php');
source.addEventListener("showStatus", function (event) {
    $("#divInfo").append(event.data+' ');
    });    
source.addEventListener("close", function (event) {
    source.close();
    });
</script>

Explications :

  • dans l’élément <div id="divInfo"></div> on va écrire les messages reçus, en l’espèce les nombres de 1 à 15.
  • if(typeof(EventSource) == "undefined") : on vérifie si l’objet EventSource est supporté par le navigateur. Seul Internet Explorer n’est pas compatible.
  • var source = new EventSource('demo-sse.php'); : création de l’objet EventSource et on appelle le script PHP.
  • source.addEventListener("showStatus", function (event) : on ajoute un évènement “d’écoute” pour les mentions “showStatus” envoyées par le serveur.
  • source.close(); : lorsque le serveur envoie “close”, le script cesse d’être à l’écoute.

Pour aller plus loin

Vous l’avez compris, cette API SSE est unidirectionnelle : du serveur vers le client. Pour dialoguer dans les deux sens, voyez du côté des websockets.

Références


Partagez cet article


A lire également Tous les articles