WebSocket

[toc]

Introduction to the

WebSocket protocol (RFC 6455) is a full-duplex communication mode based on TCP protocol provided by HTML5. WebSocket protocol is designed to replace polling and Comet technology, so that the client has real-time communication capability.

Advantages of WebSocket over HTTP

The main disadvantages of the HTTP protocol are as follows.

(1) HTTP is a half-duplex protocol. Half-duplex index data can be transmitted in both client and server directions, but not at the same time. It means that data is transmitted in only one direction at a time;

(2) HTTP messages are verbose;

(3) Hacking attacks against server push. For example, long polling.

WebSocket protocol features:

(1) single TCP connection, Cao Yong duplex mode communication;

(2) Transparent to proxy, firewall and router;

(3) No header information, cookies and authentication;

(4) No security overhead;

(5) Keep the link active through the “Ping /pong” frame;

(6) The server can actively transfer messages to the client without the client polling.

WebSocket communication process

Connection is established

The client and server establish a connection through an HTTP handshake request. An HTTP request is made by the client. Unlike a normal HTTP request, this request contains some additional header information, where “Upgrade: WebSocket” indicates that this is an HTTP request for a protocol Upgrade.

The client sends the following HTTP packets:

GET /handshake HTTP / 1.1
Host: localhost:8080
Upgrade: websocket 
Connection: Upgrade 
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080
Copy the code

After receiving the handshake request, the server generates a response packet with status code 101 and returns it to the client, indicating that the handshake is successful.

The response from the server is as follows:

HTTP / 1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp
Copy the code

Data communication

After the handshake succeeds, the client and server can communicate with each other in full-duplex mode. The data type of communication can be either text data or binary data.

Connection is closed

The underlying TCP connection, under normal circumstances, should be closed by the server first. In abnormal cases, the client can initiate TCP Close. So when the server is instructed to Close the WebSocket connection, it should immediately initiate a TCP Close operation; The client should wait for the server’s TCP Close.

The WebSocket handshake closing message has a status code and an optional reason for closing. It must send a Close control frame as required by the protocol. When receiving the Close control frame instruction, the peer end must actively Close the WebSocket connection.

use

The following are common scenarios for using WebSocket in Java.

  • Native annotations

    WebSocket API implemented by Tomcat, in the Javax. WebSocket package.

  • The Spring assembly

    Handle HandshakeInterceptor and WebSocket events by inheriting from Spring’s HandshakeInterceptor and WebSocketHandler.

  • Spring STOMP

    Details below.

STOMP

An overview of the

STOMP (Simple Text Oriented Messaging Protocol) is a Messaging Protocol originally created for scripting languages such as Python/Perl/Ruby to connect to Message Broker, It can also be used over reliable full-duplex communication protocols such as TCP and WebSocket. Although STOMP is a text protocol, its message payload can be text or binary.

STOMP is a frame-based protocol modeled after HTTP, with the following frame structure.

COMMAND
header1:value1
header2:value2

Body^@
Copy the code

Clients use SEND or SUBSCRIBE commands to SEND or SUBSCRIBE messages. The destination field in the header describes the destination of the message, usually with /topic/ for one-to-many and /queue/ for point-to-point.

This is a simple publish-subscribe mechanism that sends messages to the server or to other clients through the broker.

Subscribe to messages:

SUBSCRIBE
id:sub-1
destination:/topic/price.stock.*

^@
Copy the code

Send a message:

SEND
destination:/queue/trade
content-type:application/json
content-length:44

{"action":"BUY","ticker":"MMM","shares",44}^@
Copy the code

The server broadcasts a message to all subscribers:

MESSAGE MESSAGE - id: subscription nxahklf6-1: destination: sub - 1 / topic/price. Stock. MMM {" ticker ":" MMM, "" price" : 129.45} ^ @Copy the code

The server cannot send unrequested messages. All messages sent by all servers must be in response to a particular client subscription. The subscription- ID in the server header must match the header ID subscribed to by the client.

Service side message flow

Here is a brief introduction to one of the concepts associated with messages in Spring-Messing.

  • Message: a Message, including headers and payload.
  • MessageHandler: Used to process messages.
  • MessageChannel: Used to send messages that make producers and consumers loosely coupled.

The client on the upper left is a production client that sends a SEND command to a destination address. The lower left client is a consumer client that subscribes to a destination address and receives messages pushed from this address.

Application destination address /app: Messages sent to such destination addresses are routed to one of the application processes before reaching the broker. This is equivalent to intercepting messages entering the broker in order to do some business processing on the message.

Non-application destination address/Topic: Messages sent to this destination address are forwarded directly to the broker and will not be intercepted by the application.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // HTTP handshake endpoint
        registry.addEndpoint("/portfolio");
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // The destination prefix sent by the client to the server
        registry.setApplicationDestinationPrefixes("/app");
        / / SimpleBroker prefix
        registry.enableSimpleBroker("/topic"); }}Copy the code

Annotations using

@MessageMapping

Annotate a class or method with @messagemapping. By default, the mapping value is an ant-style path mode, e.g. /thing*, /thing/**, /thing/{id}. These values can be referenced by the @destinationVariable method parameter.

Supported method parameters:

  • Message
  • MessageHeaders
  • MessageHeaderAccessor, SimpMessageHeaderAccessor, StompHeaderAccessor
  • @Payload
  • @Header
  • @Headers
  • @DestinationVariable
  • java.security.Principal

The @Messagemapping response is serialized by MessageConverter and forwarded to the broker to the destination of the request prefixed with /topic. You can also re-specify destination via @sendto or @sendtouser.

@SubscribeMapping

The @subscribeMapping annotated method returns values that are asynchronously responded to the client. You can also use @sendto or @sendtouser to re-specify destination.

@MessageExceptionHandler

When processing a message, it is possible to get an error and throw an exception. Because of the asynchronous nature of STOMP messages, the sender may never know that an error occurred. The method annotated by @messageExceptionHandler handles exceptions thrown in message methods. We can send errors to the user’s specific destination, and then the user subscribes to the message from that destination, so that the user knows what’s wrong with them.

reference

Spring WebSocket official documentation

Spring Session official documentation