1. An overview of the

The message broker we used in the previous article is Spring’s built-in simple message broker. Simple message broker is perfect for getting started. However, only a subset of STOMP commands are supported (such as acks, receipts are not supported), rely on message sending loops, and clustering is not supported. We can use an external message broker (such as RabbitMQ, ActiveMQ) to implement a fully functional message broker. This article uses RabbitMQ integration as an example. The main contents of this paper are as follows:

  • Preparation and flow of webSocket message broker using RabbitMQ
  • Spring Boot uses RabbitMQ to do the main websocket code
  • Demonstrates the use of RabbitMQ for different purposes (destinations)

2. Prepare and process the WebSocket message proxy using RabbitMQ

For RabbitMQ usage, please refer to this author’s RabbitMQ series

2.1. Prepare the WebSocket message proxy using RabbitMQ

We chose a fully functional message broker like RabbitMQ. After the message broker is installed, run the service in a STOMP-enabled case. We start the rabbitmq_web_stomp plugin on RabbitMQ

  1. Start rabbitmq_web_stomp on RabbitMQ and run the following command on RabbitMQ: sudo rabbitmq-plugins enable rabbitmq_web_stomp
  2. Log in to the RabbitMQ management platform and the following information is displayed. The STOMp proxy service is enabled

2.2. Message flow diagram

The main difference between this diagram and using simple messages is that the “Broker Relay” is used to deliver messages over TCP to an external STOMP broker (in this case, RabbitMQ) and from the broker to the subscribing customer

3. Spring Boot uses RabbitMQ to do the main websocket code

3.1. The pom. The XML

Start by adding the following JARS based on the previous article

<! -- https://mvnrepository.com/artifact/io.projectreactor/reactor-net --> <dependency> < the groupId > IO. Projectreactor < / groupId > < artifactId > reactor -.net < / artifactId > < version > mid-atlantic moved. RELEASE < / version > < / dependency > <! -- https://mvnrepository.com/artifact/io.netty/netty-all --> <dependency> <groupId>io.netty</groupId> < artifactId > netty -all < / artifactId > < version > 4.1.22. The Final < / version > < / dependency >Copy the code

3.2. BroadcastRabbitMQCtl

BroadcastCtl (BroadcastCtl

3.3. WebSocketRabbitMQMessageBrokerConfigurer configuration

Configure external Rabibitmq instead of Simple Broker: In the configureMessageBroker() method, configure the external RabbitMQ address and account password to connect to RabbitMQ

@configuration // This annotation uses THE STOMP protocol to transport messages based on the message broker, At this point you can @ Controller class using the @ MessageMapping @ EnableWebSocketMessageBroker public class WebSocketRabbitMQMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry Registry) {/** * Register Stomp endpoints ** addEndpoint: Add Stomp endpoints. * withSockJS: Specifies the endpoint to use the SockJS protocol */ registry.addendpoint ("/websocket-rabbitmq").withSockJS(); } @override public void configureMessageBroker(MessageBrokerRegistry) {/** * configureMessageBroker * use RabbitMQ as message broker. Replace the default Simple Broker */ registry //"STOMP broker relay"Process all messages to send messages to an external message broker. EnableStompBrokerRelay ("/exchange"."/topic"."/queue"."/amq/queue")
                .setRelayHost("192.168.0.113")
                .setClientLogin("hry")
                .setClientPasscode("hry")
                .setSystemLogin("hry")
                .setSystemPasscode("hry") .setSystemHeartbeatSendInterval(5000) .setSystemHeartbeatReceiveInterval(4000); ; }}Copy the code

3.4. Ws – broadcast – the rabbitmq. JSP

The JSP here is similar to the JSP above, which is omitted here

3.5. Test method

Perform startup categories: WebSocketRabbitMQApplication if the connection is the RabbitMQ, will print the following information:

The 2018-03-26 23:22:04. 354 [reactor - TCP - IO - 1] INFO O.S.M.S.S.S tompBrokerRelayMessageHandler -"System"The session connected. 2018-03-26 23:22:04. 358 [reactor - TCP - IO - 1] INFO O.S.M.S.S.S tompBrokerRelayMessageHandler - BrokerAvailabilityEvent[available=true, StompBrokerRelay [192.168.0.113:61613]]Copy the code

Test request: see http://127.0.0.1:8080//broadcast-rabbitmq/index concrete test configuration below

4. Demonstrate the use of RabbitMQ for different destinations

The prefix WebSocketRabbitMQMessageBrokerConfigurer, we need to configure the message broker. Valid destination prefixes in RabbitMQ: /temp-queue, /exchange, /topic, /queue, /amq/queue, /reply-queue/. We demonstrate the use of the last four

4.1. / exchange/exchangename / [routing_key]

Parameter Description A. /exchange: fixed value B. exchangename: switch name c. [routing_key] : routing key. This parameter is optional

For the receiver, the destination creates a unique, auto-deleted random queue and binds it to the given Exchangename according to the ROUTing_key to implement message subscription to that queue. For the sender side, the message is sent to exchangename defined and routing_key specified.

Make the following changes in the code base of this article

  1. Create a RabbitMQ switch on RabbitMQ

  2. Modify the sender code in BroadcastRabbitMQCtl

    SendTo("/exchange/rabbitmq/get-response"Public ResponseMessage broadcast(RequestMessage RequestMessage){... }Copy the code
  3. Modify the receiver’s code in ws-broadcast-rabbitmq. JSP

    stompClient.subscribe('/exchange/rabbitmq/get-response'.function(respnose){
                    showResponse(JSON.parse(respnose.body).responseMessage);
                })
    Copy the code

Test: open two pages, one page sends 3 times, the 3 messages are received by both

4.2. / queue/queuename

Using the default switch to subscribe/publish messages, stomp automatically creates a persistent queue by default. Parameter description A. /queue: fixed value b. Queuename: automatically creates a persistent queue

For receivers, subscribe to queuename. For receivers, SEND messages to Queuename. [For SEND Frame, destination will define a shared queue only on the first time it sends a message]

Make the following changes in the code base of this article

  1. Modify the code in BroadcastRabbitMQCtl

    @SendTo("/queue/rabbitmq"Public ResponseMessage broadcast(RequestMessage RequestMessage){... }Copy the code
  2. Modify the receiver’s code in ws-broadcast-rabbitmq. JSP

     
    stompClient.subscribe(
                    '/queue/rabbitmq'.function(respnose){
                    showResponse(JSON.parse(respnose.body).responseMessage);
                });
    Copy the code

Test: open two pages, one page sends 7 times, these 7 messages are received by the two pages in turn

4.3. / amq/queue/queuename

/queue/queuename = /queue/queuename The difference with /queue/ Queuename is that queues are not automatically created by STOMp and do not fail

In this case neither the sender nor the receiver will queue. But if the queue does not exist, the receiver will report an error.

Make the following changes in the code base of this article

  1. Manually create a queue named rabbitmq2 on RabbitMQ

  2. Modify the code in BroadcastRabbitMQCtl

    @SendTo("/amq/queue/rabbitmq2")
        public ResponseMessage broadcast(RequestMessage requestMessage){
    ..
    }
    Copy the code
  3. Modify the receiver’s code in ws-broadcast-rabbitmq. JSP

     
    stompClient.subscribe(
                    '/amq/queue/rabbitmq2'.function(respnose){
                    showResponse(JSON.parse(respnose.body).responseMessage);
                });
    Copy the code

Test: For SUBCRIBE frames, destination implements message subscription to the queue. For SEND Frame, messages are sent directly to the queue using the default Exhcange.

Two pages are opened, and one page sends seven messages, which are received alternately by the two pages

4.4. / topic/routing_key

Subscribe/publish messages via the AMq. topic switch, which creates a temporary queue by default and binds to topic via routing_key a. / TOPIC: fixed prefix B. Routing_key: routing key

On the sender side, an automatically deleted, non-persistent queue is created and bound to the AMQ.topic switch according to the ROUTing_key, and a subscription to the queue is implemented. On the sender side, messages are sent to the AMQ.Topic switch.

Make the following changes in the code base of this article

  1. Modify the code in BroadcastRabbitMQCtl

     @SendTo("/topic/get-response"Public ResponseMessage broadcast(RequestMessage RequestMessage){... }Copy the code
  2. Modify the receiver’s code in ws-broadcast-rabbitmq. JSP

    stompClient.subscribe(
                    '/topic/get-response'.function(respnose){
                    showResponse(JSON.parse(respnose.body).responseMessage);
                });
    Copy the code

Test: open two pages, send one page 4 times, these 4 messages are received by both simultaneously

5. The code

Please use tag V0.20 as much as possible. Do not use master, because master changes all the time. There is no guarantee that the code in this article will always be the same as the code on Github