Een Java-client voor een WebSockets-API

1. Inleiding

HTTP (Hypertext Transfer Protocol) is een staatloos verzoek-antwoordprotocol. Het eenvoudige ontwerp maakt het zeer schaalbaar, maar ongeschikt en inefficiënt voor zeer interactieve real-time webapplicaties vanwege de hoeveelheid overhead die moet worden verzonden samen met elk verzoek / antwoord.

Omdat HTTP synchroon is en real-time applicaties asynchroon moeten zijn, zijn oplossingen zoals polling of long polling (Comet) vaak gecompliceerd en inefficiënt.

Om het hierboven gespecificeerde probleem op te lossen, hebben we een op standaarden gebaseerd, bidirectioneel en full-duplex protocol nodig dat door zowel servers als clients kan worden gebruikt, en dit leidde tot de introductie van JSR 356 API - in dit artikel hebben we ' Ik zal een voorbeeld van het gebruik ervan laten zien.

2. Installatie

Laten we de Spring WebSocket-afhankelijkheden aan ons project toevoegen:

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

We kunnen altijd de laatste versies van de afhankelijkheden van Maven Central krijgen voor spring-websocket en spring-messaging.

3. STOMP

Stream Text-Oriented Messaging Protocol (STOMP) is een eenvoudig, interoperabel draadformaat waarmee client en servers kunnen communiceren met bijna alle message brokers. Het is een alternatief voor AMQP (Advanced Message Queuing Protocol) en JMS (Java Messaging Service).

STOMP definieert een protocol voor client / server om te communiceren met behulp van messaging-semantiek. De semantiek bevindt zich bovenop de WebSockets en definieert frames die worden toegewezen aan WebSockets-frames.

Het gebruik van STOMP geeft ons de flexibiliteit om clients en servers in verschillende programmeertalen te ontwikkelen. In dit huidige voorbeeld zullen we STOMP gebruiken voor berichtenuitwisseling tussen client en server.

4. WebSocket-server

In dit artikel kunt u meer lezen over het bouwen van WebSocket-servers.

5. WebSocket-client

Om met de WebSocket-server te communiceren, moet de client de WebSocket-verbinding tot stand brengen door een HTTP-verzoek te verzenden naar een server met een Upgrade koptekst correct ingesteld:

GET ws: //websocket.example.com/ HTTP / 1.1 Oorsprong: //example.com Verbinding: Upgrade Host: websocket.example.com Upgrade: websocket

Houd er rekening mee dat de WebSocket-URL's ws en wss schema's, de tweede betekent beveiligde WebSockets.

De server reageert terug door het Upgrade header in het antwoord als WebSockets-ondersteuning is ingeschakeld.

HTTP / 1.1 101 WebSocket Protocol Handshake Datum: wo 16 oktober 2013 10:07:34 GMT Verbinding: Upgrade Upgrade: WebSocket

Zodra dit proces (ook bekend als WebSocket-handshake) is voltooid, wordt de initiële HTTP-verbinding vervangen door een WebSocket-verbinding bovenop dezelfde TCP / IP-verbinding, waarna beide partijen gegevens kunnen delen.

Deze verbinding aan de clientzijde wordt geïnitieerd door WebSocketStompClient voorbeeld.

5.1. De WebSocketStompClient

Zoals beschreven in sectie 3, moeten we eerst een WebSocket-verbinding tot stand brengen en dit doen we met WebSocketClient klasse.

De WebSocketClient kan worden geconfigureerd met:

  • StandardWebSocketClient geleverd door elke JSR-356-implementatie zoals Tyrus
  • JettyWebSocketClient geleverd door Jetty 9+ native WebSocket API
  • Elke implementatie van Spring's WebSocketClient

We zullen gebruiken StandardWebSocketClient, een implementatie van WebSocketClient in ons voorbeeld:

WebSocketClient client = nieuwe StandardWebSocketClient (); WebSocketStompClient stompClient = nieuwe WebSocketStompClient (client); stompClient.setMessageConverter (nieuwe MappingJackson2MessageConverter ()); StompSessionHandler sessionHandler = nieuwe MyStompSessionHandler (); stompClient.connect (URL, sessionHandler); nieuwe scanner (System.in) .nextLine (); // Sluit niet onmiddellijk. 

Standaard, WebSocketStompClient ondersteunt SimpleMessageConverter. Omdat we te maken hebben met JSON-berichten, stellen we de berichtconvertor in op Toewijzing Jackson2MessageConverter om de JSON-payload naar object te converteren.

Terwijl we verbinding maken met een eindpunt, geven we een instantie door van StompSessionHandler, die de gebeurtenissen afhandelt zoals afterConnected en handleFrame.

Als onze server SockJs-ondersteuning heeft, kunnen we de client aanpassen om te gebruiken SockJsClient in plaats van StandardWebSocketClient.

5.2. De StompSessionHandler

We kunnen een StompSession om u te abonneren op een WebSocket-onderwerp. Dit kan worden gedaan door een instantie van StompSessionHandlerAdapter die op zijn beurt het StompSessionHandler.

EEN StompSessionHandler biedt levenscyclusgebeurtenissen voor een STOMP-sessie. De gebeurtenissen omvatten een callback wanneer de sessie tot stand is gebracht en meldingen in geval van storingen.

Zodra de WebSocket-client verbinding maakt met het eindpunt, wordt het StompSessionHandler wordt aangemeld en het afterConnected () methode wordt aangeroepen waar we de StompSession abonneren op het onderwerp:

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

Zorg ervoor dat de WebSocket-server draait en de client draait, het bericht wordt op de console weergegeven:

INFO obwclient.MyStompSessionHandler - Nieuwe sessie tot stand gebracht: 53b993eb-7ad6-4470-dd80-c4cfdab7f2ba INFO obwclient.MyStompSessionHandler - Geabonneerd op / onderwerp / berichten INFO obwclient.MyStompSessionHandler - Bericht verzonden naar websessionHandler-server INFO Howdy !! van: Nicky 

6. Conclusie

In deze korte tutorial hebben we een op Spring gebaseerde WebSocket-client geïmplementeerd.

De volledige implementatie was te vinden op GitHub.