Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Jakarta EE
  3. Introduction aux WebSockets
Extrait - Jakarta EE Développez des applications web en Java
Extraits du livre
Jakarta EE Développez des applications web en Java Revenir à la page d'achat du livre

Introduction aux WebSockets

Introduction

Les WebSockets permettent de pallier une problématique grandissante dans le monde web.

Il est très courant d’avoir besoin d’une application web réactive dont le contenu doit se mettre à jour automatiquement sans intervention de l’utilisateur. Le souci est que le protocole HTTP sous-jacent fonctionne en mode déconnecté sous la forme d’un couple requête/réponse. Le client est donc obligé de faire une requête à chaque fois qu’il souhaite obtenir une réponse du serveur.

La solution classique est donc l’utilisation de la technologie AJAX en JavaScript pour effectuer des requêtes asynchrones en tâche de fond. Ainsi, la page web envoie à intervalle régulier une requête vers le serveur pour obtenir des informations actualisées. Plusieurs inconvénients à cette solution peuvent être cités, parmi lesquels :

  • L’exécution d’un grand nombre de requêtes augmente le trafic réseau d’autant plus qu’à chaque fois, la requête contient des en-têtes, d’éventuels cookies...

  • Les requêtes exécutées peuvent être inutiles car les données demandées n’ont pas été modifiées depuis la dernière requête.

La solution proposée par les WebSockets est d’utiliser...

Le fonctionnement

1. Les étapes de la communication

Trois étapes constituent la communication par WebSocket :

  • La première étape est la mise en place de la communication (appelée handshake) où les deux parties se partagent des informations d’identification. C’est le client qui doit initier la communication.

  • La seconde étape est la communication à proprement parler ou les deux parties peuvent envoyer des données à l’autre partie indépendamment de l’autre.

  • La dernière étape est la fermeture de la communication. Elle peut être réalisée par n’importe lesquelles de deux parties.

2. L’établissement de la communication

L’établissement de la communication par WebSocket doit pouvoir se faire sur le même port que les requêtes HTTP classiques. La requête cliente initiant la communication est donc tout simplement une requête HTTP.

Cette requête possède des en-têtes particuliers qui permettent ensuite de communiquer sur le protocole WebSocket.

Voici un exemple de ce type de requête :

images/07EP01N.png

La requête est classique (protocole, URL, méthode). Les différences se situent dans les en-têtes de requête et de réponse. Les en-têtes Connection et Upgrade permettent de demander l’établissement d’une connexion avec le protocole...

La spécification WebSocket

La spécification WebSocket (actuellement dans sa version 2.0) respecte le protocole WebSocket. Elle est consultable à l’adresse suivante : https://jakarta.ee/specifications/websocket/2.0/websocket-spec-2.0.pdf

Elle permet, sur la partie serveur, d’exposer des ressources pouvant envoyer des messages ou réagir à l’établissement de la connexion (@OnOpen), à la réception d’un message (@OnMessage) ou à la fermeture de la connexion (@OnClose).

Elle permet, sur la partie cliente (écrite en Java), de demander l’établissement d’une connexion en plus des possibilités offertes sur la partie serveur.

Bien sûr, la partie cliente ne peut pas exposer de ressources.

La spécification WebSocket propose la possibilité de mettre en place un conteneur de WebSockets autonome. Dans le cadre de l’ouvrage, le déploiement se fera au sein d’une instance de Tomcat 10.

N’importe quel client respectant le protocole WebSocket peut interagir avec la ressource exposée. Dans le cadre de l’ouvrage, deux exemples sont présentés :

  • Un accès depuis une application cliente écrite en Java.

  • Un accès depuis une application cliente écrite en JavaScript.

L’exemple

L’exemple à l’appui de la présentation permettra d’alerter les visiteurs d’une page du nombre de personnes présentes simultanément sur cette page.

Dans le cadre de la gestion du complexe sportif, il peut être intéressant d’indiquer le nombre de personnes présentes sur la page de réservation des terrains pour inciter le visiteur à prendre une décision.

Pour cela, l’usage des WebSockets est intéressant pour signifier à tous les visiteurs l’arrivée d’un nouveau visiteur.

Le côté serveur

1. La mise en place de l’environnement de développement

L’objectif de ce chapitre est d’appréhender le fonctionnement des websockets au travers d’un projet exemple nommé Projet_WebSocket.

 Commencez par créer un projet de type Gradle Project avec les mêmes caractéristiques que dans le premier chapitre.

 Complétez l’arborescence de répertoires pour qu’elle ressemble à cela :

images/07EP02N.png

 Ajoutez un fichier nommé web.xml dans le répertoire src/main/webapp/WEB-INF avec un contenu équivalent au projet initial (PremierProjetWEB). Veillez simplement à renommer le nom du projet au sein de la balise <display-name>.

 Modifiez le fichier build.gradle avec le contenu suivant :

plugins { 
    id 'java' 
    id 'war' 
} 
 
repositories { 
    jcenter() 
} 
 
dependencies { 
    compileOnly group: 'jakarta.websocket', name: 
'jakarta.websocket-api', version: '2.0.0' 
} 

 Observez la section dependencies : la dépendance est définie avec le mot-clé compileOnly car elle est uniquement nécessaire au moment de la compilation. Ce n’est pas une erreur. Tomcat 10 embarque nativement une implémentation de la spécification WebSocket.

2. Le développement par annotations

Introduction

Le développement des WebSockets peut se faire par l’utilisation d’annotations sur des classes POJO. C’est la manière retenue dans l’ouvrage pour faire la présentation.

Les annotations sont présentes dans les packages jakarta.websocket et jakarta.websocket.server

@ServerEndPoint

L’annotation @ServerEndPoint permet de déclarer une classe POJO comme étant un point de terminaison côté serveur (Server End Point). Cette annotation attend un paramètre value permettant de définir l’URL de la ressource associée. Dans la suite de l’ouvrage, cette classe sera nommée WebSocket.

Voici un exemple de mise en œuvre :

@ServerEndpoint(value="/acces") 
public class CompteurAccesWebSocket  
{ 
    ... 
}...

Le côté serveur de l’exemple

 Dans le package fr.editions_eni.jakartaee.websocket.server_end_ points, créez la classe CompteurAccesWebSocket :

@ServerEndpoint(value="/acces") 
public class CompteurAccesWebSocket { 
 
    private static final Set<Session> sessionsActives =  
Collections.synchronizedSet(new HashSet<Session>()); 
 
    private void avertir() 
    { 
        try { 
            for(Session sessionActive :sessionsActives) 
            {     
                System.out.println("avertissement d'une session"); 
                if(sessionActive.isOpen()) 
                { 
                    sessionActive.getBasicRemote().sendText(String.
valueOf(sessionsActives.size())); 
                } 
            } 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
    } 
    @OnMessage ...

Le côté client en Java

1. Introduction

La spécification WebSocket décrit une API cliente permettant de communiquer avec une ressource exposée avec l’annotation @ServerEndPoint. Les acteurs principaux sont :

  • L’annotation @ClientEndPoint,

  • L’interface jakarta.websocket.WebSocketContainer.

2. La mise en place de l’environnement de développement

Dans le cadre de l’ouvrage, l’application cliente sera développée sous la forme d’une console Java classique à partir d’un projet Gradle nommé Projet_Client_WebSocket.

Lorsque le projet est créé, il reste à modifier le fichier build.gradle pour mettre en place les dépendances suivantes afin d’obtenir l’implémentation Tomcat de la partie client de la spécification WebSocket :

implementation group: 'org.apache.tomcat', name: 'tomcat-websocket', 
version: '10.0.7' 
implementation group: 'org.apache.tomcat', name: 'tomcat-api', 
version: '10.0.7' 

Rafraîchissez votre projet pour qu’il soit prêt pour le développement.

3. Le développement par annotations

Introduction

Comme pour le côté serveur, il est possible de développer la partie cliente avec des annotations. La différence avec la partie serveur est l’impossibilité d’utiliser l’annotation @ServerEndPoint. Il est donc...

Le côté client en JavaScript

1. Introduction

Les navigateurs modernes permettent d’établir une communication par WebSocket avec une ressource exposée sur un serveur. Vous pouvez visualiser en détail la liste des navigateurs compatibles à l’adresse suivante : http://caniuse.com/#feat=websockets

Pour résumer, voici les versions minimales des navigateurs les plus courants :

  • Internet Explorer 10 et plus,

  • Edge 12 et plus,

  • Firefox 11 et plus,

  • Chrome 16 et plus,

  • Safari 7 et plus,

  • Opera 12.1 et plus.

2. L’interface WebSocket

Le langage JavaScript propose une interface nommée WebSocket et décrite par le W3C. Sa définition est accessible à l’URL suivante : https://websockets.spec.whatwg.org/

Ce qu’il faut retenir, c’est qu’il y a quatre gestionnaires d’événements (EventHandler) permettant de gérer les différentes étapes de la communication :

  • onmessage,

  • onopen,

  • onclose,

  • onerror.

À ces différents EventHandler, il est possible d’associer une méthode qui sera appelée lors de la survenue de l’événement.

À côté de ces EventHandler, la méthode send() permet d’envoyer un message passé en paramètre.

3. Le côté client de l’exemple

L’exemple consiste en une page web HTML nommée...

Conclusion

Ce chapitre a permis de faire un premier tour d’horizon sur cette technologie importante dans le développement web. Pour approfondir le sujet, n’hésitez pas à consulter la documentation officielle sur le site de Jakarta EE (https://jakarta.ee/) et celle du W3C.