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频道

相关推荐
全栈凯哥33 分钟前
16.Spring Boot 国际化完全指南
java·spring boot·后端
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
如何使用Java WebSocket API实现客户端和服务器端的通信?
java·开发语言·websocket
后端小肥肠3 小时前
效率革命!10分钟用Dify+Spring Boot打造AI热点雷达,自媒体选赛道再不难!(附保姆级教程)
人工智能·spring boot·agent
Linn4 小时前
Spring WebSocket 服务实现的主流方案与最佳实践
spring boot·后端·spring
我是老孙4 小时前
Spring Boot 应用中,配置的加载优先级
spring boot·后端·pycharm
风象南5 小时前
基于 SpringBoot 的 REST API 与 RPC 调用的统一封装
java·spring boot·后端
weixin_456904276 小时前
Spring Boot整合MyBatis+MySQL+Redis单表CRUD教程
spring boot·mysql·mybatis
努力的小郑7 小时前
Spring事件监听器深度指南:3大企业级实战场景+避坑技巧,从原理到架构决策
java·spring boot
武昌库里写JAVA7 小时前
使用 Java 开发大数据应用:Hadoop 与 Java API 的结合
java·开发语言·spring boot·学习·课程设计
亲爱的非洲野猪8 小时前
Spring Cloud Gateway介绍 - -基础概念,简单工作原理和配置示例
java·spring boot·gateway