Server push
Problème : AJAX est unidirectionnel
- Le client envoie des données dans la requête,
- Le server répond avec des données.
- Le server ne peut pas initier un transfert de données ;
- Le server ne peut pas appeler des fonctions (déclencher des évènements) chez le client.
Simuler une communication bidirectionnelle (Comet)
- Short polling, Long polling, Streaming.
Vraie communication bidirectionnelle
EventSource
, WebSockets.
Polling
Utile pour : notifications, compatibilité avec vieux browsers
Short polling
- Le client envoie une requête AJAX à intervalles réguliers (de l’ordre de la seconde),
- S’il y a des notifications depuis la dernière requête, le server les envoie dans la réponse.
Long polling, Streaming
- Le client ouvre une connexion HTTP avec le server,
- Le server envoie les entêtes mais ne ferme pas la connexion,
- Lorsque des notifications arrivent, le server les envoie dans la connexion ;
- (long polling) Le server ferme la connexion.
Polling
Avantages
- Compatible avec les vieux browsers,
- Ne demande pas de support spécifique chez le server.
Désavantages
- Gourmand en bande passante et ressources (overhead du protocole HTTP),
- Latence.
Event stream
Format de streaming unidirectionnel Server → Client : la connexion reste ouverte
HTTP/1.1 200 OK
Content-Type: text/event-stream
...
data: un message
data: un autre
data: message
event: toto
data: un message avec un nom
data: { "msg" : ["Porquoi", "pas", "du", "JSON"] }
- Un message d’une ligne,
- Un message sur plusieurs lignes,
- Un message nommé,
- On est libres de choisir le format des données.
Exemple de event stream : seveur
app.get('/api/notifications', function(req, res) {
res.set({ // Configuration des entêtes
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
}); // On envoye les entêtes
res.writeHead(200);
var count = 0; // On envoie un message
var timer = setInterval(function() { // toutes les 2 secondes
res.write('data: Hello ' + count + '\n\n');
count++;
if (count >= 10) { // Après 10 messages on
res.end(); // ferme la connexion
clearInterval(timer);
}
}, 2000);
});
- Facile en Node.js,
- Nécessite configuration spécifique pour Apache+PHP.
Exemple EventSource
: client
Le client est notifié des messages du server par des évènements
var evt = new EventSource("/api/notifications");
// Messages sans nom
evt.addEventListener('message', function(e) {
console.log(e.data);
});
// Messages nommés
evt.addEventListener('toto', function(e) {
console.log('Évènement nommé :', e.data);
});
- Pour : Léger, simple, relativement bien supporté,
- Contre : Unidirectionnel, nécessite le support du serveur,
- Démo : http://server-sent-events-demo.herokuapp.com/.
Web Sockets
Protocole de communication full-duplex, compatible avec HTTP.
- Protocole applicatif au dessus de TCP : pas de overhead HTTP ;
- Conçu pour utiliser le même port que HTTP (port 80 par défaut).
GET /app/socket HTTP/1.1
Upgrade: websocket
Connection: Upgrade
...
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
...
- Le client demande une connexion web socket,
- Le server répond avec
101 Switching Protocols
, - Le server et le client établissent une connexion TCP de type Web
(schema
ws://
) Socket.
Web Sockets
Avantages
- Bidirectionnels,
- Peu de overhead,
- Standardisés par l’IETF en 2011.
Désavantages
- Nécessitent de support dans le server,
- Pas adaptés au modèle d’exécution Apache+PHP,
- API pas encore standardisée par le W3C.
Bibliothèques
- Node.js : module
websocket
, http://socket.io/ (cross browser, très simple à utiliser), - PHP : http://socketo.me/ (très difficile à configuer).