Un client Java pour une API WebSockets

1. Introduction

HTTP (Hypertext Transfer Protocol) est un protocole de requête-réponse sans état. Sa conception simple le rend très évolutif mais inadapté et inefficace pour les applications Web en temps réel hautement interactives en raison de la quantité de frais généraux qui doit être transmise avec chaque demande / réponse.

Puisque HTTP est synchrone et que les applications en temps réel doivent être asynchrones, toutes les solutions telles que l'interrogation ou l'interrogation longue (Comet) ont tendance à être compliquées et inefficaces.

Pour résoudre le problème spécifié ci-dessus, nous avons besoin d'un protocole basé sur des normes, bidirectionnel et full-duplex qui pourrait être utilisé par les serveurs et les clients, ce qui a conduit à l'introduction de l'API JSR 356 - dans cet article, nous ' Je vais en montrer un exemple d'utilisation.

2. Configuration

Incluons les dépendances Spring WebSocket dans notre projet:

 org.springframework spring-websocket 5.2.2.RELEASE   org.springframework spring-messaging 5.2.2.RELEASE 

Nous pouvons toujours obtenir les dernières versions des dépendances auprès de Maven Central pour spring-websocket et spring-messaging.

3. STOMP

Le protocole STOMP (Stream Text-Oriented Messaging Protocol) est un format filaire simple et interopérable qui permet au client et aux serveurs de communiquer avec presque tous les courtiers de messages. C'est une alternative à AMQP (Advanced Message Queuing Protocol) et JMS (Java Messaging Service).

STOMP définit un protocole permettant au client / serveur de communiquer à l'aide de la sémantique de messagerie. La sémantique se trouve au-dessus des WebSockets et définit les cadres qui sont mappés sur les cadres WebSockets.

L'utilisation de STOMP nous donne la flexibilité de développer des clients et des serveurs dans différents langages de programmation. Dans cet exemple actuel, nous utiliserons STOMP pour la messagerie entre le client et le serveur.

4. Serveur WebSocket

Vous pouvez en savoir plus sur la création de serveurs WebSocket dans cet article.

5. Client WebSocket

Pour communiquer avec le serveur WebSocket, le client doit lancer la connexion WebSocket en envoyant une requête HTTP à un serveur avec une mise à niveau jeu d' en- tête correctement:

GET ws://websocket.example.com/ HTTP/1.1 Origin: //example.com Connection: Upgrade Host: websocket.example.com Upgrade: websocket

Veuillez noter que les URL WebSocket utilisent des schémas ws et wss , le second signifie des WebSockets sécurisés.

Le serveur répond en envoyant l'en- tête Upgrade dans la réponse si la prise en charge WebSockets est activée.

HTTP/1.1 101 WebSocket Protocol Handshake Date: Wed, 16 Oct 2013 10:07:34 GMT Connection: Upgrade Upgrade: WebSocket

Une fois ce processus (également appelé prise de contact WebSocket) terminé, la connexion HTTP initiale est remplacée par une connexion WebSocket en plus de la même connexion TCP / IP, après quoi les deux parties peuvent partager des données.

Cette connexion côté client est initiée par l' instance WebSocketStompClient .

5.1. Le WebSocketStompClient

Comme décrit dans la section 3, nous devons d'abord établir une connexion WebSocket, et cela se fait à l'aide de la classe WebSocketClient .

Le WebSocketClient peut être configuré en utilisant:

  • StandardWebSocketClient fourni par n'importe quelle implémentation JSR-356 comme Tyrus
  • JettyWebSocketClient fourni par l'API WebSocket native de Jetty 9+
  • Toute implémentation de WebSocketClient de Spring

Nous utiliserons StandardWebSocketClient , une implémentation de WebSocketClient dans notre exemple:

WebSocketClient client = new StandardWebSocketClient(); WebSocketStompClient stompClient = new WebSocketStompClient(client); stompClient.setMessageConverter(new MappingJackson2MessageConverter()); StompSessionHandler sessionHandler = new MyStompSessionHandler(); stompClient.connect(URL, sessionHandler); new Scanner(System.in).nextLine(); // Don't close immediately. 

Par défaut, WebSocketStompClient prend en charge SimpleMessageConverter . Puisque nous traitons des messages JSON, nous définissons le convertisseur de messages sur MappingJackson2MessageConverter afin de convertir la charge utile JSON en objet.

Lors de la connexion à un point de terminaison, nous transmettons une instance de StompSessionHandler , qui gère les événements tels que afterConnected et handleFrame .

Si notre serveur prend en charge SockJs, nous pouvons alors modifier le client pour utiliser SockJsClient au lieu de StandardWebSocketClient.

5.2. Le StompSessionHandler

Nous pouvons utiliser une StompSession pour nous abonner à un sujet WebSocket. Cela peut être fait en créant une instance de StompSessionHandlerAdapter qui à son tour implémente StompSessionHandler .

Un StompSessionHandler fournit des événements de cycle de vie pour une session STOMP. Les événements incluent un rappel lorsque la session est établie et des notifications en cas d'échec.

Dès que le client WebSocket se connecte au point de terminaison, le StompSessionHandler est notifié et la méthode afterConnected () est appelée là où nous utilisons la StompSession pour nous abonner à la rubrique:

@Override public void afterConnected( StompSession session, StompHeaders connectedHeaders) { session.subscribe("/topic/messages", this); session.send("/app/chat", getSampleMessage()); } @Override public void handleFrame(StompHeaders headers, Object payload) { Message msg = (Message) payload; logger.info("Received : " + msg.getText()+ " from : " + msg.getFrom()); }

Assurez-vous que le serveur WebSocket est en cours d'exécution et exécute le client, le message sera affiché sur la console:

INFO o.b.w.client.MyStompSessionHandler - New session established : 53b993eb-7ad6-4470-dd80-c4cfdab7f2ba INFO o.b.w.client.MyStompSessionHandler - Subscribed to /topic/messages INFO o.b.w.client.MyStompSessionHandler - Message sent to websocket server INFO o.b.w.client.MyStompSessionHandler - Received : Howdy!! from : Nicky 

6. Conclusion

Dans ce tutoriel rapide, nous avons implémenté un client WebSocket basé sur Spring.

L'implémentation complète peut être trouvée sur GitHub.