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

相关推荐
爱上语文11 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
荆州克莱13 分钟前
springcloud整合nacos、sentinal、springcloud-gateway,springboot security、oauth2总结
spring boot·spring·spring cloud·css3·技术
serve the people15 分钟前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
罗政6 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
Java小白笔记9 小时前
关于使用Mybatis-Plus 自动填充功能失效问题
spring boot·后端·mybatis
小哇6669 小时前
Spring Boot,在应用程序启动后执行某些 SQL 语句
数据库·spring boot·sql
superconvert10 小时前
主流流媒体的综合性能大 PK ( smart_rtmpd, srs, zlm, nginx rtmp )
websocket·ffmpeg·webrtc·hevc·rtmp·h264·hls·dash·rtsp·srt·flv
luoluoal11 小时前
java项目之企业级工位管理系统源码(springboot)
java·开发语言·spring boot
蜜桃小阿雯12 小时前
JAVA开源项目 校园美食分享平台 计算机毕业设计
java·jvm·spring boot·spring cloud·intellij-idea·美食
计算机学姐12 小时前
基于SpringBoot+Vue的篮球馆会员信息管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis