Spring Boot项目中使用WebSocket消息代理功能

  1. 添加依赖 :在pom.xml文件中添加Spring Boot的WebSocket依赖。

    复制代码
    <dependencies>
        <!-- Spring Boot Starter Websocket -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
    </dependencies>
  2. WebSocket配置类 (WebSocketConfig.java):

    import org.springframework.context.annotation.Configuration;
    import org.springframework.messaging.simp.config.MessageBrokerRegistry;
    import org.springframework.web.socket.config.annotation.*;

    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    复制代码
     @Override
     public void registerStompEndpoints(StompEndpointRegistry registry) {
         //这个代表了前端需要通过/ws路径来建立连接
         registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
     }
    
     @Override
     public void configureMessageBroker(MessageBrokerRegistry registry) {
         //这个你就把它当作创建了"/topic", "/queue"这两个频道,然后前端建立连接后
         //可以监听这两个频道,后端发送消息到这其中频道后,前端可以接收到
         registry.enableSimpleBroker("/topic", "/queue");
         //这个代表前端可以通过/user开头的地址,来给服务端发送消息,服务端可以用     
         //@MessageMapping注解来接收消息
         // @MessageMapping("/sendMessage") 例如这样写,前端就需要通过/user/sendMessage来给后        
         //端的这个方法发送消息
         registry.setUserDestinationPrefix("/user");
     }

    }

WebSocket控制器 (WebSocketController.java):

复制代码
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class WebSocketController {
    //接收客户端向/user/sendMessage这个地址发送的消息
    @MessageMapping("/sendMessage")
    //把接收来的这个消息发送到所有订阅/topic/messages地址的客户端
    @SendTo("/topic/messages")
    public String processMessageFromClient(String message) {
        return "Server response: " + message;
    }
}

让你更便于理解,我这么写:

当客户端通过 /sendMessage 发送消息时,processMessageFromClient 方法会被调用,并将消息传递给 sendToTopicMessages 方法。sendToTopicMessages 方法会返回一个格式化的响应消息,该消息会被发送到 /topic/messages 主题(订阅频道)。

复制代码
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class WebSocketController {

    @MessageMapping("/sendMessage")
    public String processMessageFromClient(String message) {
        // 调用 sendToTopicMessages 并使用其返回值
        return sendToTopicMessages(message);
    }

    @SendTo("/topic/messages")
    public String sendToTopicMessages(String message) {
        // 返回服务器响应的消息
        return "Server response: " + message;
    }
}

当然你也可以不适用@SendTo注解来向订阅地址发送消息。

SimpMessagingTemplate 是 Spring Framework 中的一个类,它提供了向 WebSocket 客户端发送消息的多种方法。

复制代码
以下是一些主要方法:

1. **convertAndSend**:这是最常用的方法,用于将消息转换并发送到指定目的地。它支持发送文本消息、二进制消息和对象消息等。例如,`convertAndSend("/topic/greetings", "Hello World!")` 会向所有订阅了 `/topic/greetings` 的客户端发送一条文本消息  。

2. **convertAndSendToUser**:此方法允许你向特定用户发送消息。它需要用户的标识符、目的地和消息内容。例如,`convertAndSendToUser("user1", "/queue/notifications", message)` 会向用户 `user1` 发送消息  。

3. **setUserDestinationPrefix**:设置用于针对特定用户的目标地址的前缀。默认值是 `"/user/"`。此方法通常与 `convertAndSendToUser` 结合使用,以确保消息发送到正确的用户端点 。

4. **getMessageChannel**:返回配置的消息通道,该通道用于发送消息 。

5. **setSendTimeout** 和 **getSendTimeout**:用于设置和获取发送操作的超时时间(以毫秒为单位)。

6. **send**:发送一个 `Message` 对象到指定的目的地。如果消息头中已经包含了目的地,则消息将直接发送到该目的地;如果没有,则会发送到配置的默认目的地 。

`SimpMessagingTemplate` 的使用需要在项目中添加 Spring Boot 的 WebSocket 依赖 `spring-boot-starter-websocket` 。通过注入 `SimpMessagingTemplate` 的实例,你可以在 Spring Boot 应用程序的任何地方发送消息,甚至不必首先接收一条消息作为前提 。

在实际开发中,`SimpMessagingTemplate` 可以用于实现如聊天应用、实时数据推送等需要 WebSocket 通信的功能。使用时,可以通过配置文件或注解来启用 WebSocket 支持,并利用 `SimpMessagingTemplate` 的方法来处理消息的发送 。

前端页面 (index.html):

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script>
</head>
<body>
    <h1>WebSocket Demo</h1>
    <input type="text" id="message" placeholder="Type a message">
    <button onclick="sendMessage()">Send</button>
    <h2>Messages</h2>
    <ul id="messages"></ul>

    <script type="text/javascript">
        const socket = new SockJS('/ws');
        const stompClient = Stomp.over(socket);
        let connected = false;

        function connect() {
            stompClient.connect({}, frame => {
                connected = true;
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/messages', message => displayMessage(message));
            });
        }

        function sendMessage() {
            const messageInput = document.getElementById('message');
            if (connected) {
                stompClient.send("/app/sendMessage", {}, messageInput.value);
                messageInput.value = '';
            } else {
                alert("Please connect first!");
            }
        }

        function displayMessage(message) {
            const messagesList = document.getElementById('messages');
            const messageItem = document.createElement('li');
            messageItem.textContent = message.body;
            messagesList.appendChild(messageItem);
        }

        socket.onclose = () => {
            connected = false;
            console.log("Disconnected");
        };

        window.onload = connect; // Connect when the page loads
    </script>
</body>
</html>

这样你打开html页面,可以多开几个浏览器。

然后在任意页面发送消息,其他浏览器都会接收并且显示出来,包括发送方的页面也会显示。因为大家都订阅了/topic/messages频道

相关推荐
xuxie1317 分钟前
SpringBoot文件下载(多文件以zip形式,单文件格式不变)
java·spring boot·后端
LiRuiJie1 小时前
深入剖析Spring Boot / Spring 应用中可自定义的扩展点
java·spring boot·spring
朝阳5812 小时前
用 Rust + Actix-Web 打造“Hello, WebSocket!”——从握手到回声,只需 50 行代码
前端·websocket·rust
尚学教辅学习资料4 小时前
Ruoyi-vue-plus-5.x第五篇Spring框架核心技术:5.1 Spring Boot自动配置
vue.js·spring boot·spring
晚安里4 小时前
Spring 框架(IoC、AOP、Spring Boot) 的必会知识点汇总
java·spring boot·spring
上官浩仁5 小时前
springboot ioc 控制反转入门与实战
java·spring boot·spring
叫我阿柒啊5 小时前
从Java全栈到前端框架:一位程序员的实战之路
java·spring boot·微服务·消息队列·vue3·前端开发·后端开发
中国胖子风清扬6 小时前
Rust 序列化技术全解析:从基础到实战
开发语言·c++·spring boot·vscode·后端·中间件·rust
JosieBook10 小时前
【SpringBoot】21-Spring Boot中Web页面抽取公共页面的完整实践
前端·spring boot·python
刘一说10 小时前
Spring Boot+Nacos+MySQL微服务问题排查指南
spring boot·mysql·微服务