websocket demo based on stomp protocol

What is stomp

STOMP (Simple (or Streaming) Text Orientated Messaging Protocol) is a simple text protocol that defines the format for communication between clients and message brokers. It is an interoperable protocol because many different message brokers and clients implement it. STOMP provides a reliable, asynchronous messaging model that is suitable for communicating between heterogeneous systems, such as those written in different programming languages. The STOMP protocol is becoming more and more popular due to its simplicity and interoperability.

Code Sample Outline

  1. The backend publishes socket messages and subscribes to channels

  1. Front-end connection back-end socket

  1. One front-end sends a message, and multiple front-ends receive the message at the same time

Backend code

Enable websocket “/endpointWisely”, generate subscription channel “/topic”

package com.websocket;


import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * describe
 *
 * @author huangjuan
 * @date 2023/2/20 16:21
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/endpointWisely").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
    }
}

springmvc view /ws maps to ws.html

package com.websocket;

import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

/**
 * describe
 *
 * @author huangjuan
 * @date 2023/2/21 9:31
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/ws").setViewName("ws.html");
        registry.addViewController("/index").setViewName("index.html");
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/css/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/css/");
        registry.addResourceHandler("/js/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/js/");
        super. addResourceHandlers(registry);
    }
}

Front-end request method “/welcome”

package com.websocket;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

/**
 * describe
 *
 * @author huangjuan
 * @date 2023/2/21 9:19
 */
@Controller
public class WsController {
    @MessageMapping("/welcome")
    @SendTo("/topic/getResponse")
    public WiselyResponse say(WiselyMessage wiselyMessage) throws InterruptedException {
        Thread. sleep(3000);
        return new WiselyResponse("Welcome, " + wiselyMessage.getName() + "!");
    }
}

related beans

package com.websocket;

/**
 * describe
 *
 * @author huangjuan
 * @date 2023/2/21 9:22
 */
public class WiselyMessage {
    private String name;

    public String getName() {
        return name;
    }

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

/**
 * describe
 *
 * @author huangjuan
 * @date 2023/2/21 9:19
 */
public class WiselyResponse {
    private String responseMessage;
    public WiselyResponse(String responseMessage) {
        this.responseMessage = responseMessage;
    }

    public String getResponseMessage() {
        return responseMessage;
    }

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

front page

connect, send message to channel

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Spring boot + Websocket broadcast test</title>
</head>
<body onload="disconnect()">
<noscript>
    <h2 style="color: #ff0000">Looks like your browser does not support websocket</h2>
</noscript>
<div>
    <div>
        <button id="connect" onclick="connect()">Connect</button>
        <button id="disconnect" onclick="disconnect()" disabled="disabled">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>
</body>
<script src="/js/sockjs.min.js"></script>
<script src="/js/stomp.min.js"></script>
<script src="/js/jquery.min.3.2.1.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';
    }
    function connect() {
        var socket = new SockJS("/endpointWisely");
        stompClient = Stomp.over(socket);
        stompClient. connect({}, function (frame) {
            setConnected(true);
            console.log("connected!" + frame)
            stompClient. subscribe("/topic/getResponse", function (response) {
                console. log(response)
                showResponse(JSON. parse(response. body). responseMessage)
            });
        });
    }
    function disconnect() {
        if (stompClient != null) {
            stompClient. disconnect();
        }
        setConnected(false);
        console.log("disconnected!")
    }
    function showResponse(message) {
        var response = document. getElementById("response");
        response.innerHTML=message;
    }
    function sendName() {
        var name = document.getElementById("name").value;
        alert(name)
        stompClient.send("/welcome", {}, JSON.stringify({'name': name}));
    }
</script>
</html>

quoted js