Un client Java pour une API WebSockets

Un client Java pour une API WebSockets

1. introduction

HTTP (Hypertext Transfer Protocol) est un protocole de demande-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 surcharge de temps 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 standard, bidirectionnel et full-duplex qui pourrait être utilisé à la fois par les serveurs et les clients, ce qui a conduit à l'introduction deJSR 356 API - dans cet article, nous en montrerons un exemple d'utilisation.

2. Installer

Incluons les dépendances Spring WebSocket à notre projet:


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

Nous pouvons toujours obtenir les dernières versions des dépendances auprès de Maven Central pourspring-websocket etspring-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 aux protocoles 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 des cadres mappés sur des cadres WebSockets.

L'utilisation de STOMP nous donne la possibilité 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 cearticle.

5. WebSocket Client

Pour communiquer avec le serveur WebSocket, le client doit initier la connexion WebSocket en envoyant une requête HTTP à un serveur avec un en-têteUpgrade correctement défini:

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

Veuillez noter que les URL WebSocket utilisent les schémasws etwss, le second signifie des WebSockets sécurisés.

Le serveur répond en envoyant l'en-têteUpgrade 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é négociation WebSocket) terminé, la connexion HTTP initiale est remplacée par la connexion WebSocket au-dessus 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'instanceWebSocketStompClient.

5.1. LesWebSocketStompClient

Comme décrit dans la section 3, nous devons d'abord établir une connexion WebSocket, et cela se fait en utilisant la classeWebSocketClient.

LesWebSocketClient peuvent être configurés en utilisant:

  • StandardWebSocketClient fourni par toute implémentation JSR-356 comme Tyrus

  • JettyWebSocketClient fournis par l'API WebSocket native de Jetty 9+

  • Toute implémentation desWebSocketClient de Spring

Nous utiliseronsStandardWebSocketClient, une implémentation deWebSocketClient 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 chargeSimpleMessageConverter. Puisque nous traitons des messages JSON, nous définissons le convertisseur de message surMappingJackson2MessageConverter afin de convertir la charge utile JSON en objet.

Lors de la connexion à un point de terminaison, nous transmettons une instance deStompSessionHandler, qui gère les événements tels queafterConnected ethandleFrame.

Si notre serveur prend en charge SockJs, nous pouvons modifier le client pour utiliserSockJsClient au lieu deStandardWebSocketClient.

5.2. LesStompSessionHandler

Nous pouvons utiliser unStompSession pour vous abonner à une rubrique WebSocket. Cela peut être fait en créant une instance deStompSessionHandlerAdapter qui à son tour implémente lesStompSessionHandler.

UnStompSessionHandler 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, leStompSessionHandler est notifié et la méthodeafterConnected() est appelée là où nous utilisons lesStompSession 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 exécute 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 rapide tutoriel, nous avons implémenté un client WebSocket basé sur Spring.

L'implémentation complète a pu être trouvéeover on GitHub.