1. 引入依赖
在你的Spring Boot项目的pom.xml中添加以下依赖:
<dependencies>
        <!-- Spring Boot Starter Thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- Spring Boot Starter WebSocket -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>
    </dependencies>
2. 配置WebSocket
创建一个配置类来设置WebSocket连接端点、STOMP协议和消息传输路径:
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketMessageBrokerConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws") // WebSocket握手端口
                .setAllowedOriginPatterns("*") // 设置跨域
                .withSockJS(); // 开启SockJS回退机制
    }
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app") // 发送到服务端目的地前缀
                .enableSimpleBroker("/topic");// 开启简单消息代理,指定消息订阅前缀
    }
}
3. 创建消息处理器
创建一个控制器来处理客户端发送的消息,并将消息广播给订阅了相关主题的客户端:
/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2024-08-05 17:24
 */
@Controller
@Slf4j
@RequiredArgsConstructor
public class StompController {
    private final SimpMessagingTemplate messagingTemplate;
    @GetMapping("stomp")
    public ModelAndView stomp() {
        return new ModelAndView("stomp");
    }
    /**
     * 数据通过前端发送到后端,处理完数据后在响应给前端的订阅者“/topic/public”
     * @param chatMessage
     * @return
     */
    // 这个注解的作用是映射客户端发送到服务器的消息路径
    @MessageMapping("/chat.sendMessage")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(ChatMessage chatMessage) {
        return chatMessage;
    }
    @MessageMapping("/chat.addUser")
    @SendTo("/topic/public")
    public ChatMessage addUser(ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) {
        // 将用户名存储在WebSocket会话中
        headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
        return chatMessage;
    }
    /**
     * 服务端主动给客户端发送消息
     * @return
     */
    @GetMapping("s-to-c")
    @SendTo("/topic/public")
    @ResponseBody
    public ChatMessage sToC() {
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setContent("西瓜视频");
        chatMessage.setSender("Server");
        chatMessage.setType(ChatMessage.MessageType.CHAT);
        // 发送消息
        messagingTemplate.convertAndSend("/topic/public", chatMessage);
        return chatMessage;
    }
    @GetMapping("/html/greeting")
    public ModelAndView turnToGreetingPage() {
        return new ModelAndView("greeting");
    }
    @MessageMapping("/greeting")
    public String sayGreeting(String name) {
        log.info("Message received: {}", name);
        return "Hello, " + name;
    }
}
4. 创建消息模型
创建一个简单的Java类来表示聊天消息:
/**
 * 聊天消息对象
 */
@Data
public class ChatMessage {
    /**
     * 消息的类型
     */
    private MessageType type;
    /**
     * 消息的内容
     */
    private String content;
    /**
     * 发送者
     */
    private String sender;
    public enum MessageType {
        //普通聊天消息
        CHAT,
        // 加入聊天
        JOIN,
        // 离开聊天
        LEAVE
    }
}
5. 创建前端代码(stomp.html)
在前端(例如使用HTML和JavaScript)中集成WebSocket和STOMP。以下是一个简单的示例:
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket-Chat-stomp</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.6.1/sockjs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
    <script>
        var stompClient = null;
        // 接收消息
        function connect() {
            var socket = new SockJS('/ws');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function (frame) {
                console.log('Connected: ' + frame);
                // 客户端订阅服务端消息
                stompClient.subscribe('/topic/public', function (message) {
                    showMessage(JSON.parse(message.body));
                });
            });
        }
        // 发送消息
        function sendMessage() {
            var messageContent = document.getElementById("message").value;
            // 往客户端发送消息
            stompClient.send("/app/chat.sendMessage", {}, JSON.stringify({
                sender: "User",
                content: messageContent,
                type: 'CHAT'
            }));
        }
        // 展示消息
        function showMessage(message) {
            var response = document.getElementById("response");
            var p = document.createElement("p");
            p.appendChild(document.createTextNode(message.sender + ": " + message.content));
            response.appendChild(p);
        }
        // 用户加入
        function addUser() {
            var userName = document.getElementById('username').value;
            if (userName && stompClient) {
                var chatMessage = {
                    sender: userName,
                    content: userName + "已加入聊天!请注意财产安全",
                    type: 'JOIN'
                };
                stompClient.send("/app/chat.addUser", {}, JSON.stringify(chatMessage));
            }
        }
    </script>
</head>
<body onload="connect()">
<div>
    <input type="text" id="username" placeholder="Enter your name" />
    <button onclick="addUser()">用户加入</button>
    <input type="text" id="message" />
    <button onclick="sendMessage()">发送信息</button>
</div>
<div id="response"></div>
</body>
</html>
7. yml配置
server:
  port: 9999
#  servlet:
#    context-path: /demo
spring:
  freemarker:
    request-context-attribute: request
    suffix: .html
    content-type: text/html
    enabled: true
    cache: false
    charset: UTF-8
    allow-request-override: false
    expose-request-attributes: true
    expose-session-attributes: true
    expose-spring-macro-helpers: true
8. 运行应用程序
启动Spring Boot应用程序,并打开你的HTML页面,你应该能够通过WebSocket连接发送和接收消息了。
| 链接 | 说明 | 
|---|---|
| http://localhost:9999/stomp | 第一个客户端 | 
| http://localhost:9999/stomp | 第二个客户端 | 
| http://localhost:9999/s-to-c | 服务端主动给客户端发送消息 | 
1.前端

2.用户加入

3.聊天消息

4.服务端主动给客户端发送消息


总结
通过以上步骤,你可以在Spring Boot项目中集成WebSocket和STOMP协议,实现实时的双向通信功能。这是一个基本的示例,你可以根据需要进行扩展和自定义,例如添加更多的消息处理逻辑、安全认证等。



















