https://d226lax1qjow5r.cloudfront.net/blog/blogposts/creating-a-websocket-server-with-spring-boot/springboot_websocket.png

Créer un serveur WebSocket avec Spring Boot

Publié le June 24, 2021

Temps de lecture : 3 minutes

WebSocket est un protocole qui permet la communication entre le serveur et le navigateur. Il présente un avantage par rapport à RESTful HTTP car les communications sont à la fois bidirectionnelles et en temps réel. Cela permet au serveur d'informer le client à tout moment, au lieu que le client demande des mises à jour à intervalles réguliers.

Dans cette série de billets, je vais vous montrer trois façons différentes de créer un serveur WebSocket en Java en utilisant Spring Bootle Spark Frameworket l API Java pour WebSockets.

Conditions préalables

Vous utiliserez Gradle pour gérer vos dépendances et exécuter votre application.

En outre, vous devez vous assurer qu'une copie du JDK est installée. J'utiliserai le JDK 8 dans ce tutoriel.

WebSockets avec Spring Boot

Spring Boot vous permet de créer des applications Spring de niveau production à l'intérieur d'un JAR exécutable.

Créer le projet

Vous pouvez utiliser Spring Initializr pour démarrer votre application et sélectionner les packages dont vous avez besoin.

Pour cet exemple, vous aurez besoin de la dépendance Websocket . J'utiliserai également Gradle, vous voudrez donc le modifier pour générer un projet Gradle.

Spring Initializer HomepageSpring Initializer Homepage

En cliquant sur le bouton Générer un projet, vous téléchargez un fichier zip. Décompressez-le dans un répertoire de votre choix.

Créer le gestionnaire WebSocket

Les messages WebSocket peuvent être à la fois textuels et binaires. Vous allez créer un gestionnaire capable de traiter ces deux types de messages.

Créer une nouvelle classe appelée WebSocketHandler qui étend AbstractWebSocketHandler dans le paquet com.example.websocketdemo dans le paquetage. AbstractWebSocketHandler Cette classe doit implémenter deux méthodes, handleTextMessage et handleBinaryMessage qui sont appelées lorsqu'un nouveau message textuel ou binaire est reçu.

À des fins de démonstration, vous allez créer un serveur d'écho qui renverra le message reçu à l'expéditeur.

Ajouter les implémentations suivantes :

@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
    System.out.println("New Text Message Received");
    session.sendMessage(message);
}

@Override
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws IOException {
    System.out.println("New Binary Message Received");
    session.sendMessage(message);
}

Enregistrer le gestionnaire WebSocket

Pour pouvoir utiliser le WebSocketHandleril doit être enregistré dans la base de données WebSocketHandlerRegistry. Ce qui suit permet d'accomplir deux choses :

  1. Il enregistrera le WebSocketHandler sur le chemin /socket chemin.

  2. Il permettra à tous les clients du navigateur d'envoyer des messages au serveur. Ils ne seront pas obligés d'avoir une origine spécifique.

Créer une nouvelle classe appelée WebSocketConfiguration qui implémente l'interface WebSocketConfigurer dans le paquet com.example.websocketdemo paquet.

Annoter WebSocketConfiguration à l'aide des boutons @Configuration et @EnableWebSocket annotations.

WebSocketConfigurer exige que vous mettiez en œuvre une registerWebSocketHandlers méthode.

Ajouter l'implémentation suivante au registre WebSocketHandler:

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(new WebSocketHandler(), "/socket").setAllowedOrigins("*");
}

Étant donné que vous aurez à traiter des messages binaires en plus des messages texte, il est judicieux de définir la taille maximale des messages binaires. Cette valeur est stockée dans le conteneur de serveur. Vous pouvez surcharger cette valeur en injectant une nouvelle fabrique de conteneur de serveur dans votre fichier WebSocketConfiguration.

Ajoutez le code suivant pour injecter un nouveau ServletServerContainerFactoryBean dans WebSocketConfiguration au-dessus de la méthode registerWebSocketHandlers que vous avez précédemment ajoutée :

@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setMaxBinaryMessageBufferSize(1024000);
    return container;
}

Cela permet de télécharger une image d'une taille maximale de 1 Mo.

Créer un client pour tester votre application

Vous devrez créer un client pour tester votre serveur WebSocket. Vous voudrez tester l'envoi de messages textuels et binaires. Cela peut être réalisé avec JavaScript.

Ajoutez ce qui suit à index.html à l'intérieur du dossier src/main/resources/static à l'intérieur du dossier

<html>
<head>
    <style>
        #messages {
            text-align: left;
            width: 50%;
            padding: 1em;
            border: 1px solid black;
        }
    </style>
    <title>Sample WebSocket Client</title>
</head>
<body>
<div class="container">
    <div id="messages" class="messages"></div>
    <div class="input-fields">
        <p>Type a message and hit send:</p>
        <input id="message"/>
        <button id="send">Send</button>

        <p>Select an image and hit send:</p>
        <input type="file" id="file" accept="image/*"/>

        <button id="sendImage">Send Image</button>
    </div>
</div>
</body>
<script>
    const messageWindow = document.getElementById("messages");

    const sendButton = document.getElementById("send");
    const messageInput = document.getElementById("message");

    const fileInput = document.getElementById("file");
    const sendImageButton = document.getElementById("sendImage");

    const socket = new WebSocket("ws://localhost:8080/socket");
    socket.binaryType = "arraybuffer";

    socket.onopen = function (event) {
        addMessageToWindow("Connected");
    };

    socket.onmessage = function (event) {
        if (event.data instanceof ArrayBuffer) {
            addMessageToWindow('Got Image:');
            addImageToWindow(event.data);
        } else {
            addMessageToWindow(`Got Message: ${event.data}`);
        }
    };

    sendButton.onclick = function (event) {
        sendMessage(messageInput.value);
        messageInput.value = "";
    };

    sendImageButton.onclick = function (event) {
        let file = fileInput.files[0];
        sendMessage(file);
        fileInput.value = null;
    };

    function sendMessage(message) {
        socket.send(message);
        addMessageToWindow("Sent Message: " + message);
    }

    function addMessageToWindow(message) {
        messageWindow.innerHTML += `<div>${message}</div>`
    }

    function addImageToWindow(image) {
        let url = URL.createObjectURL(new Blob([image]));
        messageWindow.innerHTML += `<img src="${url}"/>`
    }
</script>
</html>

Démarrer l'application

Votre serveur WebSocket est maintenant terminé. Démarrez votre application en utilisant la commande gradle bootRun dans le répertoire de l'application.

Vous pouvez accéder à votre application à l'adresse suivante http://localhost:8080 où vous serez accueilli par la page suivante :

Sample JavaScript-enabled client for testing the WebSocket serverSample JavaScript-enabled client for testing the WebSocket server

Le message "connecté" indique que le client JavaScript a pu établir une connexion.

Essayez d'envoyer un message texte en tapant dans le champ de saisie et en cliquant sur le bouton d'envoi. Essayez également de télécharger une image. Dans les deux cas, vous devriez voir le même message et la même image renvoyés.

Sample JavaScript-enabled client showing a text and binary message echoed backSample JavaScript-enabled client showing a text and binary message echoed back

Conclusion

Dans ce tutoriel, vous avez appris à créer un serveur WebSocket à l'aide de Spring Boot qui peut recevoir des messages binaires et textuels. Le code complet de ce tutoriel se trouve sur le site Web de nexmo-community/websocket-spring-boot sur le dépôt nexmo-community/websocket-spring-boot.

Avez-vous essayé le Spark Framework ? Vous voudrez peut-être voir comment Créer un serveur WebSocket à l'aide de Spark Framework.

Saviez-vous que vous pouvez utiliser WebSocket comme point de terminaison dans un objet de contrôle d'appel? Regardez cet exemple sur Flux d'appels vers un navigateur avec des WebSockets Voice.

Partager:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Steve CrowAnciens de Vonage

Steve est un mathématicien autoproclamé et le roi du sarcasme. Il aime aussi les lévriers, les puzzles tortueux et les jeux de société européens. Lorsqu'il ne parle pas de mathématiques à des personnes qui n'en font pas, ou de Java à des personnes qui n'en font pas, on peut le trouver en train de siroter un café et de bidouiller du code.