SpringBook Actual Warfare (XVI) | Integrating WebSocket to Realize Broadcast Messages Based on STOMP Protocol

Time:2019-9-10

Preface

For example, today’s introduction is SpringBoot’s integration of WebSocket for broadcasting messages.

What is WebSocket?

WebSocket provides browsers and servers with the function of duplex asynchronous communication, that is, browsers can send information to the server, and vice versa.

WebSocket achieves duplex asynchronous communication capability through a socket, but it is very tedious to use WebSocket directly (or simulation of SockJS: WebSocket protocol, which adds compatibility support that current browsers do not support using WebSocket) protocol development program, so it is very tedious to use its sub-protocol STOMP.

Brief Introduction to STOMP Protocol

It is an advanced streaming text oriented message protocol and a simple text protocol designed for MOM (Message Oriented Middleware).

It provides an interoperable connection format that allows STOMP clients to interact with any STOMP message broker, similar to OpenWire (a binary protocol).

Because of its simple design and easy development of client, it has been widely used in many languages and platforms. The most popular STOMP message broker is Apache ActiveMQ.

STOMP uses a frame-based format to define messages, similar to Http’s request and response.

Radio broadcast

Next, we implement a demo of broadcast messages. That is, when the server has a message, the message is sent to all browsers connected to the current endpoint.

Preparation

  • SpringBoot 2.1.3
  • IDEA
  • JDK8

Pom Dependency Configuration

<dependencies>
        <! - thymeleaf template engine - >
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <! - Web Startup Class - >
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <! - WebSocket Dependency - >
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <! - Test Unit Testing - > Test Unit Testing - > Test Unit Testing Unit Testing Unit Testing Unit Testing Unit Testing Unit Testing Unit Testing Unit Testing Unit Testing Unit
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

Code comments are very detailed, not to mention much.

Configure WebSocket

Implement the WebSocketMessage Broker Configurer interface, register a STOMP node, and configure a broadcasting message broker

@Configuration
//@ Enable WebSocket Message Broker annotation is used to turn on the use of STOMP protocol to transmit message based on Message Broker when the controller
// Start supporting @MessageMapping, just like using @request Mapping.
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // Register a Stomp node (endpoint) and specify the use of the SockJS protocol.
        registry.addEndpoint("/endpointNasus").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        // The broadcast configuration is called / nasus message broker, which must match or match the address prefix of the @SendTo configuration in the controller
        registry.enableSimpleBroker("/nasus");
    }
}

Message class

Client sends to server:

public class Client2ServerMessage {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

The server sends to the client:

public class Server2ClientMessage {

    private String responseMessage;

    public Server2ClientMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }

    public String getResponseMessage() {
        return responseMessage;
    }

    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }
}

Demonstration Controller Code

@RestController
public class WebSocketController {

    @ MessageMapping ("/hello")/@MessageMapping and @RequestMapping functions are similar. Browsers send messages to the server and map them to that address.
    @ SendTo ("/nasus/getResponse")// If the server receives the message, it sends the message to the browser that subscribes to the address in @SendTo parentheses.
    public Server2ClientMessage say(Client2ServerMessage message) throws Exception {
        Thread.sleep(3000);
        return new Server2ClientMessage("Hello," + message.getName() + "!");
    }

}

Introducing STOMP scripts

Place stomp.min.js (STOMP client script), sockJS.min.js (sockJS client script) and Jquery in the static directory of the resource folder.

Demo page

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Spring Boot+WebSocket+Broadcast</title>

</head>
<body onload="disconnect()">
<noscript><h2 style="color: ff0000">It seems that your browser does not support websocket</h2></noscript>
<div>
    <div>
        <button id= "connect" onclick= "connect ();">connect </button>
        <button id= "disconnect" disabled= "disabled" onclick= "disconnect ();">disconnect </button>
    </div>
    <div id="conversationDiv">
        < label > enter your name </label > < input type = "text" id = "name"/>.
        <button id="sendName" onclick="sendName();">Send </button>
        <p id="response"></p>
    </div>
</div>
<script th:src="@{sockjs.min.js}"></script>
<script th:src="@{stomp.min.js}"></script>
<script th:src="@{jquery.js}"></script>
<script type="text/javascript">
    var stompClient = null;

    function setConnected(connected) {
        document.getElementById('connect').disabled = connected;
        document.getElementById('disconnect').disabled = !connected;
        document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden';
        $('#response').html();
    }
    
    function connect() {
        // The endpoint name for connecting SockJs is "/ endpoint Nasus"
        var socket = new SockJS('/endpointNasus'); 
        // WebSocket Client Using STOMP Subprotocol
        stompClient = Stomp.over(socket); 
        stompClient.connect({}, function(frame) {
            setConnected(true);
            console.log('Connected: ' + frame);
            // SendTo Definition for Controller by Subscribing to / Nasus / getResponse Target via stompClient. subscribe
            stompClient.subscribe('/nasus/getResponse', function(respnose){
            // Show the returned information, and you can receive the returned information from the server as long as you subscribe to the / nasus / getResponse target
            showResponse(JSON.parse(respnose.body).responseMessage);
            });
        });
    }
    
    
    function disconnect() {
        // Disconnect
        if (stompClient != null) {
            stompClient.disconnect();
        }
        setConnected(false);
        console.log("Disconnected");
    }

    function sendName() {
        // Send a message to the server
        var name = $('#name').val();
        // Send information to / Hello (server) via stompClient. send, corresponding to the definition in controller @MessageMapping
        stompClient.send("/hello", {}, JSON.stringify({ 'name': name }));
    }

    function showResponse(message) {
          // Receive the returned message
          var response = $("#response");
          response.html(message);
    }
</script>
</body>
</html>

Page Controller

Note that the @Controller annotation is used here to match the HTML prefix and load the page.

@Controller
public class ViewController {

    @GetMapping("/nasus")
    public String getView(){
        return "nasus";
    }
}

test result

Open three windows to access http://localhost:8080/nasus. The initial page is as long as this:

Connect all three pages and click Connect to Subscribe to Endpoint as follows:

On the first page, enter the name and click Send as follows:

Send a message on the first page and wait for 3 seconds. The result is that all three pages receive the information returned by the server and broadcast successfully.

Source download:

https://github.com/turoDog/De…

If you find it helpful, please give a Star and go again. Thank you very much.

Posterior language

If this article is even a little helpful to you, please help to look good. Your good looks are the motivation for me to keep writing.

In addition, after the attention is sent1024Free learning materials are available.

See this old article for details: Python, C++, Java, Linux, Go, Front-end, Algorithmic Data Sharing

Recommended Today

Sharing 10 useful methods of laravel 5.8 sets

This article is forwarded from the professional laravel developer community, original link: https://learnku.com/laravel/t… In laravel, there is a very useful class for manipulating arrays, called collections. I believe that every developer of laravel has used the collection more or less, especially when operating eloquent. In this article, I will list 10 common methods. 1. Weight […]