Socket.io

De EduTech Wiki
Aller à la navigation Aller à la recherche

Cet article est en construction: un auteur est en train de le modifier.

En principe, le ou les auteurs en question devraient bientôt présenter une meilleure version.



Introduction

Socket.io est un module de Node.js qui permet de créer des Web Sockets, c'est-à-dire des connections bi-directionnelles entre clients et serveur qui permettent une communication en temps réel sur un autre protocole que le protocole http normalement utilisé dans les pages web. Ce type de technique est utilisée pour créer des applications telles que des système de communication en temps réel (i.e. des Chats), des jeux multi-utilisateur, des applications de collaboration, etc.

Bien que Socket.io soit un module qui peut être utilisé individuellement, la plupart des exemples contenus dans la page utilise également le module Express.js.

Objectifs de cette page

Cette page fait principalement référence au cours STIC I du Master MALTT et s'inscrit dans la perspective d'aborder les fondamentaux de la programmation à travers JavaScript. Plus en détail, Socket.io permet de montrer le fonctionnement d'un protocole plus complexe par rapport au protocole http. Grâce à ce type de communication, il est possibile de créer des applications pédagogiques, notamment en relation avec l'Apprentissage collaboratif.

De plus, la communication WebSocket renforce ultérieurement les concepts de programmation événementielle et d'interactivité, car pour mettre en place des applications qui se mettent à jour en temps réel il faut entremêler des événements côté-client et côté-serveur.

Pour comprendre le contenu de cette page la lecture des pages suivantes est conseillée :

Avertissement de sécurité

Warning.png

Le même avertissement de sécurité de Node.js s'applique dans le cas de Socket.io, car les technologies utilisées sont très similaires.

Veuillez également être attentif au fait que les exemples illustrés dans cette page ont exclusivement une finalité propédeutique à l’apprentissage des concepts fondamentaux du développement web et ne sont pas conçus pour une utilisation en dehors d’un environnement contrôlé par le développeur (e.g. localhost).

Example conceptuel: messagerie instantanée

Un exemple conceptuel peut contribuer à mettre les informations théoriques et pratiques de cette page dans une perspective plus concrète: un application de messagerie instantanée. Le principe est assez simple : un client envoie un message au serveur, le serveur reçoit ce message et le transmets aux autres clients connectés. Voici un enregistrement vidéo d'une simple application dans deux fenêtres du navigateur (représentant deux utilisateurs différents) :

Enregistrement vidéo d'une simple application de messagerie instantanée avec WebSockets.

Dans ce simple mécanisme il y a tout de même plusieurs événements qui se passent :

  1. Côté client : l’utilisateur écrit du texte et clique sur un bouton pour envoyer le message. On a donc un événement qu’on peut identifier avec le nom « messageFromClient » associé à des données de type textuel ;
  2. Côté serveur : le serveur doit « écouter » pour des événements de type « messageFromClient » pour être prêt à gérer l’information envoyé par le client ;
  3. Côté serveur : lorsque le serveur reçoit un événement « messageFromClient », il émet à son tour un événement qui transmet le message aux clients connectés. On peut identifier cet événement avec le nom « messageFromServer », associé encore une fois à des données de type textuel ;
  4. Côté client : le client doit « écouter » pour des événements de type « messageFromServer » pour être prêt à gérer l’information retransmise par le serveur ;
  5. Côté client : lorsque le client reçoit un événement « messageFromServer », il utilise les données textuelles reçues pour mettre à jour le DOM de la page HTML et afficher le nouveau message ;

Comprendre les WebSockets

Figure 1. Avant les WebSockets, le "temps réel" était en réalité un décalage régulier. Entre 1. et 3. ou 1. et 5. le temps pouvait varier entre quelques seconds et quelques minutes.
Figure 2. Avec les WebSockets la connectivité est simultanée. Le délai entre 1. et 2. est de 50-100 ms!

Différence par rapport au protocole http

Le protocole http est basée sur l’architecture requête/réponse qui peut être considéré comme la somme de deux mouvements unidirectionnels : la requête du client dans un sens et la réponse du serveur dans l’autre sens. Une fois que cet échange a eu lieu, il n’y a plus de contact entre le client et le serveur, si ce n’est à travers l’établissement d’un nouvel échange requête/réponse (Figure 1). Le protocole WebSocket, au contraire, crée une véritable connexion entre le client et le serveur, ce qui permet une communication bidirectionnelle en temps réel : le client peut envoyer un message au serveur, et le serveur peut envoyer un message à un client, sans la nécessité d’une requête/réponse http. À travers ce nouveau type de connexion, il est également possible de créer un « groupe » de communication entre tous les clients qui ont établi une connexion WebSocket avec le même serveur (Figure 2). Le principe est très simple :

  1. Un client envoie un message au serveur
  2. Le serveur reçoit le message
  3. Le serveur envoie ce même message (ou un message modifié) à tous les clients connectés

Un upgrade du protocole http

Il faut cependant considérer que le protocole des WebSockets nécessite quand même du protocole http pour établir la première connexion. En effet, le protocole des WebSockets est une sorte de « upgrade » du protocole http. Pour que cet upgrade ait lieu, il y a deux prérequis nécessaires :

  1. Le serveur est capable de gérer le protocole WebSockets : cette capacité est disponible justement grâce à la combinaison Express.js/Socket.io
  2. Le client est capable de gérer le protocole WebSockets : cette capacité est disponible à travers l’API HTML5 des WebSockets qui est compatible avec pratiquement tous les browsers récents (en 2016)

Le « handshake »

Lorsque ces prérequis sont atteints, une connexion WebSockets s’établie de la manière suivante :

  1. Un client établie une simple connexion http avec un serveur, ce qui se fait par exemple à travers la requête d’une simple page HTML avec un URL
  2. Sur cette page HTML est présent un script JavaScript qui s’occupe de démarrer une connexion WebSocket. Cette connexion s’établi seulement si le navigateur supporte l’API HTML5 des WebSockets
  3. La demande de connexion WebSockets est donc envoyé au serveur. Si le serveur supporte ce type de connexion, alors la connexion bidirectionnelle est formée : le client et le serveur seront en contact tout au long que le client garde la page avec le script JavaScript ouverte dans son navigateur

Ce type de mécanisme s’appelle « handshake », car c’est comme si les deux entités (le client et le serveur) s’accordent sur la possibilité d’établir un nouveau « pacte » (la connexion WebSockets) sur la base d’une prémisse existante (une connexion http établie et la capacité des deux entités de gérer le nouveau protocole).

L’échange de messages

Une fois le « handshake » achevé, l’échange de messages entre client et serveur peut commencer. L’échange se fait à tout moment dans lequel un événement côté client ou côté serveur déclenche l’envoie d’un message. L’échange entre les deux entités se compose de deux éléments :

  1. Le type d’événement (obligatoire)
  2. Des données associées à cet événement : les données peuvent être de différent type, du simple texte dans le cas d’un système de messagerie instantanée à des streams audio/vidéo pour des applications plus complexes

Pour que l’échange se passe correctement il faut donc que le client et le serveur, dans la logique de leurs applications, disposent d’un gestionnaire d’événement qui :

  • Sache quoi faire pour émettre un événement (avec ou sans données)
  • Sache quoi faire pour recevoir (et éventuellement réagir) à un événement

Avantages des WebSockets

Le protocole WebSockets présente plusieurs avantages par rapport au protocole http :

  • Le temps de latence pour l’envoie et la réception d’un message et d’environ 50-100 ms. En fonction du temps de réaction des êtres humains (perception, traitement, etc.), ce délai peut être considéré de facto du « real time ».
  • L’échange entre client et serveur (ou entre serveur et client) se fait seulement s’il y a un événement qui propose un changement. Ceci réduit le trafique des requêtes/réponses à l’essentiel, tandis que dans le cas des applications qui utilisent le protocole http, souvent la plupart des requêtes asynchrones est faite juste pour contrôler s’il y a quelque chose de nouveau. Toutes se requêtes ne sont pas nécessaire avec les WebSockets.
  • La communication en temps réel permet une vraie synchronisation entre les clients, ce qui permet de créer des applications collaboratives ou les apprenants partagent à tout moment le même écran et peuvent donc discuter/contribuer/etc. plus facilement.
  • L’échange de messages au niveau client se fait à travers JavaScript, ceci signifie que les informations obtenues dans les échanges peuvent être utilisées par la logique de l’application front-end.

Utilisation de Socket.io

Installation des modules

Comme tout module Node.js, Socket.io s'installe avec npm :

npm install socket.io

Bien que Socket.io puisse être utilisé individuellement, nous allons le combiner avec Express.js pour fournir également le protocole http nécessaire pour le "handshake" (voir plus haut dans la section théorique).

npm install express

=Mettre en place un serveur HTTP+WebSocket

Le fait qu'on nécessite de deux protocoles différents implique conceptuellement deux serveurs différents: un serveur qui gère le protocole http et un serveur qui gère le protocole WebSocket. En effet, il est tout à fait possible que la connexion WebSocket se fasse sur un autre serveur par rapport au serveur qui met à disposition la page HTML dans lequel se trouve le script qui crée la connexion WebSocket. En utilisant l'environnement de Node.js, il est possibile de combiner les deux serveurs dans une seule application:

  • Express.js "écoute" la requête http et se charge d'envoyer en réponse une page qui contient le JavaScript pour établir une connexion WebSocket et gérer par la suite l'échange des messages ;
  • Socket.io "écoute" et retransmet les messages entre les clients connectés et le serveur

La possibilité de combiner les deux serveurs dans la même application permet notamment de partager des informations (e.g. bases des données, etc.).