HTML5 Server-Sent Events

9 aprile 2013

La Server-Sent Events EventSource API è una libreria (HTML5, ndR) che permette di delegare al browser il monitoraggio di una sorgente di dati e di ottenere notifiche “push” dal server ad ogni nuovo evento. Con questa semplicissima API possiamo, ad esempio, tenere sotto osservazione un servizio remoto e gestire ogni messaggio da esso generato all’interno delle nostre applicazioni web.

Grazie all’estrema semplicità di utilizzo risulta un’ottima alternativa ai classici meccanismi di polling sviluppati attorno all’utilizzo di tecniche AJAX. Nonostante il loro supporto non abbracci ancora l’intero insieme dei browser di ultima generazione esistono ottime librerie capaci di emulare in modo soddisfacente questa interessante feature.

La forma più semplice di implementazione dei Server Sent Events è la seguente: supponiamo di avere un servizio remoto che, ad ogni interrogazione, restituisce l’ora corrente: implementiamo questo semplice meccanismo in PHP creando un file ‘tempo.php‘ all’interno di una cartella che abbiamo predisposto per questo progetto e che possa essere raggiungibile attraverso un web server:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
echo 'data: ' . strftime('%H:%M:%S',time()) . PHP_EOL;
echo PHP_EOL;
?>

Per prima cosa notiamo come l’output di questo script non sia HTML, ne JSON e XML ma semplice testo contenente una sola riga prefissata dalla particella ‘data:‘ e valorizzata con la data corrente, ad esempio:

data: 12:28:00

Per ogni riga ‘data:‘ seguita da una riga vuota, il browser genererà per noi un evento di tipo message, che potremo facilmente gestire.

Prima di proseguire dobbiamo sincerarci che ogni interrogazione a ‘tempo.php‘ abbia come MIME type di risposta ‘text/event-stream‘; per fare questo forziamo l’header Content-Type utilizzando il comando ‘header‘ di PHP; utilizziamo lo stesso comando anche per sincerarci che la risposta non venga memorizzata nella cache del browser con l’header Cache-Control: no-cache.

Costruiamo ora la pagina web, che possiamo chiamare index.html, per monitorare il semplice servizio appena creato:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Che ore sono?</title>
<script>
var source = new EventSource('tempo.php');
source.addEventListener('message', function (event) {
	document.querySelector('span').textContent = event.data;
});
</script>
</head>
<body>
Sono le: <span></span>
</body>
</html>

Lato front-end sintassi e implementazione di queste API sono semplicissime. È sufficiente creare un nuovo oggetto EventSource che punti alla pagina da monitorare e agganciare a questo oggetto un apposito listener per l’evento ‘message’. Nella proprietà ‘data’ dell’evento potremo trovare il contenuto testuale ricevuto dal server, in questo caso l’ora corrente.

Eventi multipli

Ecco cosa accade dietro le quinte: il browser accede ripetutamente all’indirizzo specificato come parametro nel costruttore dell’oggetto EventSource e per ogni ‘data:‘ recuperato genera un evento ‘message’ che contiene nel suo campo ‘data’ il contenuto testuale prodotto dal server. Possiamo decidere di cambiare il nome dell’evento utilizzando la sintassi ‘event: nomeevento‘; questo ci permette di gestire eventi di tipo diverso all’interno dello stesso flusso di dati.

Proviamo a modificare l’esempio precedente generando due eventi, uno ‘timerome‘ contenente l’ora corrente con il fuso orario ‘Europe/Rome’ ed un’altro ‘timenewyork‘ con la stessa ora ma nel fuso orario della grande mela; ecco il nuovo ‘tempo.php

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
date_default_timezone_set('Europe/Rome');
echo 'event: timerome' . PHP_EOL;
echo 'data: ' . strftime('%H:%M:%S',time()) . PHP_EOL;
echo PHP_EOL;
date_default_timezone_set('America/New_York');
echo 'event: timenewyork' . PHP_EOL;
echo 'data: ' . strftime('%H:%M:%S',time()) . PHP_EOL;
echo PHP_EOL;
?>

Dobbiamo effettuare alcune modifiche anche sul front-end per gestire i due eventi generati da questa sorgente dati:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Che ore sono?</title>
<script>
var source = new EventSource('tempo.php');

source.addEventListener('timerome', function (event) {
	document.querySelector('span[data-tz="rome"]').
	textContent = event.data;
});

source.addEventListener('timenewyork', function (event) {
	document.querySelector('span[data-tz="new_york"]').
	textContent = event.data;
});
</script>
</head>
<body>
Roma: <span data-tz="rome"></span><br/>
New York: <span data-tz="new_york"></span>
</body>
</html>

Nella seconda parte dell’articolo vedremo come generare grafici utilizzando l’API per la ricezione dei messaggi.

Se vuoi aggiornamenti su HTML5 Server-Sent Events inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su HTML5 Server-Sent Events

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy