spring ws stomp interface programming

Article directory

    • summary
    • Overall architecture process
    • technical details
    • summary
    • quote

Summary

In project development, using Websocket subscriptions can push data updates and changes in real time. However, there are also some pain points. First of all, Websocket subscription needs to manage the subscription object to ensure the accuracy and timeliness of the subscription. Second, subscribed messages need to be fully filtered and processed to avoid invalid and duplicate messages. At the same time, in the case of high concurrency, Websocket subscriptions also need to perform current limiting and queue management to ensure the stability and reliability of the system. In addition, Websocket subscription also needs to support multiple protocols and formats to adapt to different types of data push and processing scenarios. Therefore, when using Websocket subscriptions in projects, these issues need to be fully considered to ensure the stability, reliability and timeliness of the system.

Overall architecture process

In the project, you can manage Websocket requests uniformly by configuring a unified Websocket entry. In this way, other Websocket requests can be written, called and managed like an API, making the structure of the project clearer and more standardized. At the same time, this method can also realize the unified filtering and processing of Websocket requests, and improve the reliability and stability of the system. For developers, this can also reduce repetitive code writing and improve development efficiency. Therefore, it is recommended to use a unified Websocket entrance in the project to optimize the system structure and performance.

Technical details

You can configure multiple prefix brokers and map them to different routes as needed, but the annotations are different. Everything else has the same logic as writing the API.

Configuration:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {<!-- -->

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {<!-- -->
// registry.enableSimpleBroker("/topic");
// registry.setApplicationDestinationPrefixes("/app");

//Memory-based STOMP message broker
registry.enableSimpleBroker("/queue", "/topic");

//STOMP message broker based on RabbitMQ
/* registry.enableStompBrokerRelay("/queue", "/topic")
                .setRelayHost(host)
                .setRelayPort(port)
                .setClientLogin(userName)
                .setClientPasscode(password);*/

// registry.setApplicationDestinationPrefixes("/app", "/foo");
registry.setUserDestinationPrefix("/user");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {<!-- -->
// registry.addEndpoint("/gs-guide-websocket").withSockJS();
// registry.addEndpoint("/webSocketServer").setAllowedOrigins("*").withSockJS();
registry.addEndpoint("/webSocketServer").withSockJS();
}

}

transfer:

 @MessageMapping("/app/sendTest")
// @SendTo("/topic/subscribeTest")
    public ServerMessage sendDemo(ClientMessage message, StompHeaderAccessor stompHeaderAccessor) {<!-- -->
        Principal principal = stompHeaderAccessor.getUser();
        String name = principal.getName();
        logger.info("The authentication name is: {}, the message received is: {}", name, message);
        logger.info("Message received" + message.getName());
        return new ServerMessage("The message you sent is:" + message.getName());

    }

    @SubscribeMapping("/subscribeTest")
    @SendTo("/topic/subscribeTest")
    public ServerMessage sub() {<!-- -->
        logger.info("XXX user subscribed to me...");
        template.convertAndSend("/topic/subscribeTest", "XXX user subscribed to the room");
        return new ServerMessage("Thank you for subscribing to me...");
    }

front end:

//Establish a connection object (the connection has not been initiated yet)
  var socket = new SockJS("http://localhost:8080/webSocketServer");

  // Get the client object of the STOMP subprotocol
  var stompClient = Stomp.over(socket);

  //Initiate a websocket connection to the server and send a CONNECT frame
  stompClient.connect(
          {<!-- -->},
          function connectCallback(frame) {<!-- -->
            var userId=1;
            //Callback method when the connection is successful (the server responds to the CONNECTED frame)
            setMessageInnerHTML("Connection successful");
            stompClient.subscribe('/user/' + userId + '/queue/light', function (response) {<!-- -->
              setMessageInnerHTML("Successfully subscribed " + '/user/' + userId + '/queue/light');
              var returnData = JSON.parse(response.body);
              setMessageInnerHTML('/user/' + userId + '/queue/light' + "The message you received is:" + returnData.responseMessage);
            });
          },
          function errorCallBack(error) {<!-- -->
            //Callback method when connection fails (server responds with ERROR frame)
            setMessageInnerHTML("Connection failed");
          }
  );

  //Send a message
  function send() {<!-- -->
    var message = document.getElementById('text').value;
    var messageJson = JSON.stringify({<!-- --> "name": message });
    stompClient.send("/app/sendTest", {<!-- -->}, messageJson);
    setMessageInnerHTML("/app/sendTest The message you sent:" + message);
  }

  //Subscribe to messages
  function subscribe1() {<!-- -->
    stompClient.subscribe('/topic/subscribeTest', function (response) {<!-- -->
    // stompClient.subscribe('/ops/home/monitor/page', function (response) {<!-- -->
      setMessageInnerHTML("Successfully subscribed to /topic/subscribeTest");
        console. log(response)
        debugger
      // var returnData = JSON. parse(response. body);
      setMessageInnerHTML("/ops/home/monitor/page The message you received is:" + response);
    });
  }

There are several notes here:
@MessageMapping is an annotation in the Spring framework. It is usually used to define a method-level message handler. When a message arrives, the method will be called. The @MessageMapping annotation can be placed on a method to specify which destination messages the method should handle.

For example, when the client sends a message to the “/hello” destination, the @MessageMapping(“/hello”) annotation will tell the Spring framework that when a message arrives at the “/hello” destination, it needs to call the @MessageMapping( “/hello”) annotation method.

@MessageMapping("/hello")
public void handle(HelloMessage message) {
    // process the message
}

When a method annotated with @MessageMapping is called, the Spring framework will automatically decode the message body into method parameters and encode the response result into the message body and return it to the client. The @MessageMapping annotation is very useful for scenarios where the received message needs to be processed and a response returned.

@SubscribeMapping is an annotation used in the Spring framework to handle WebSocket subscription requests. Using this annotation allows developers to directly bind WebSocket subscription requests and post-subscription message processing methods, thereby simplifying the processing process and reducing code complexity.

When using the @SubscribeMapping annotation, developers need to add it to a method in a Controller and specify the destination of the subscription. For example:

@Controller
public class WebSocketController {<!-- -->

    @MessageMapping("/chat/{roomId}")
    public void handleChatMessage(@DestinationVariable String roomId, ChatMessage message) {<!-- -->
        // handle chat messages
    }

    @SubscribeMapping("/chat/{roomId}")
    public List<ChatMessage> subscribeChatMessages(@DestinationVariable String roomId) {<!-- -->
        // Process the subscription request and return the historical message list
    }
}

In the above code, the handleChatMessage method is used to process the message sent by WebSocket to the /chat/{roomId} destination, and the subscribeChatMessages method is used to process the message for Subscription request to the same destination and returns a list of historical messages.

By using the @SubscribeMapping annotation, developers can directly bind subscription request processing and message processing together, thereby reducing code complexity and improving development efficiency.

@SendTo is an annotation in the Spring framework, used to send messages to specified destinations. It is typically used to define a method-level message handler that will be called when a message arrives. The @SendTo annotation can be placed on a method to specify the destination to which the method will send the processing result. For example:

@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
    Thread. sleep(1000); // simulated delay
    return new Greeting("Hello, " + message. getName() + "!");
}

In the above code, when the client sends a message to the “/hello” destination, the greeting() method will be called. After processing the message, this method will send the processing result to the “/topic/greetings” destination, and notify all clients that have subscribed to this destination.

Summary

Spring STOMP is a messaging protocol based on the WebSocket protocol, which provides an easy way to implement real-time web applications. The following is a summary of the use of Spring STOMP:

  1. Configure WebSocket support

In the Spring configuration file, the WebSocket message broker needs to be enabled through the @EnableWebSocketMessageBroker annotation.

  1. Configure the STOMP endpoint

You can use the registerStompEndpoints() method to configure STOMP endpoints for receiving WebSocket connection requests from clients.

Here a STOMP endpoint named “/ws” is registered and uses the SockJS subprotocol. SockJS is a fallback protocol for the WebSocket protocol, which can provide a WebSocket-like experience when WebSocket is not available.

  1. Configure the message handler

In the Spring Framework, method-level message handlers can be declared using the @MessageMapping annotation. When a message arrives, the method annotated with @MessageMapping will be called.

  1. Configure the message broker

Spring STOMP provides a built-in message broker that can be enabled using @EnableWebSocketMessageBroker configuration.

Here a simple message broker is enabled and configured with a destination of “/topic”. When a message arrives at its destination, the broker will broadcast the message to all subscribers.

  1. Send and receive messages

A STOMP client can be used to send and receive messages. For example, in client code, you can use the StompJS library to send messages:

In a Spring application, you can use the @SendTo annotation to send a response message when processing a message.

The method annotated with @SendTo here will send the results to the “/topic/greetings” destination, and you can receive the results by subscribing to this destination on the client.

Real-time web applications can be built through them.

Cite

spring stomp

stomp