首页 > 其他分享 >构建即时通讯应用:Spring boot高效集成WebSocket、Stomp协议完成前后端持续通信

构建即时通讯应用:Spring boot高效集成WebSocket、Stomp协议完成前后端持续通信

时间:2024-08-08 22:25:23浏览次数:8  
标签:WebSocket Spring Stomp chatMessage ChatMessage 消息 return public

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 onl oad="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
1.前端

在这里插入图片描述

2.用户加入

在这里插入图片描述

3.聊天消息

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

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

源码

持续更新 (集群、优化这个应用)

标签:WebSocket,Spring,Stomp,chatMessage,ChatMessage,消息,return,public
From: https://blog.csdn.net/weixin_48278764/article/details/141037098

相关文章

  • Spring依赖注入
    概念  依赖注入(DependencyInject,缩写DI)是由Ioc容器在运行期间动态地将某种依赖资源注入对象中。  基本思想:明确地定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运行。  DI数据类型:1、基本类型与String             2、......
  • Spring注解
          1、注入类                                 替换:<beanid=""class=""></bean>                  位置:类                 语法:@Component ......
  • Java项目:213基于Springboot + vue实现的网上订餐系统(含论文+开题报告+开题PPT)
    作者主页:夜未央5788 简介:Java领域优质创作者、Java项目、学习资料、技术互助文末获取源码项目介绍基于Springboot+vue实现的网上订餐系统前台登录:1.首页:菜品信息推荐、菜品信息展示、查看更多2.菜品信息:菜品分类、菜品名称查询、菜品详情、下单提交3.个人中心:可......
  • 解决端口号占用问题:Spring Boot报错,Web server failed to start. Port 8080 was alrea
    报错信息:Webserverfailedtostart.Port8080wasalreadyinuse.报错原因:端口被占用解决方法:解决方法一:修改端口修改配置文件,加上参数:server.port=8014或者在application.yml文件中添加server:port:8014在访问时,替换对应的端口号即可解决方法二:关闭占用端口的......
  • 解决Spring报错:Failed to read candidate component class: file [ ]; nested exceptio
    使用IDEA建立一个很基础的Spring项目时,之前用xml方式,写bean标签一直正常使用,改用注解方式后发现报错,显示:Exceptioninthread"XXX"org.springframework.beans.factory.BeanDefinitionStoreException:Failedtoreadcandidatecomponentclass:file[XXX.class];nestedexc......
  • Spring Boot 3.0新特性概述
    在SpringBoot3.0中,有一些重要的更新值得关注:内置声明式HTTP客户端:Spring框架支持将远程HTTP服务代理为带有HTTP交换注解的方法的Java接口。改进的性能和稳定性:SpringBoot3.0对底层框架进行了优化,提高了应用的启动速度和运行时性能。增强的安全性:加强了对安全性的支持,包括......
  • Spring关于bean的一些基本知识
    在spring这座大厦中,去除掉最底部的核心(core)组件,那么最重要的无疑是bean和bean工厂。剩余是AOP、设计模式,更之上的就是各种组件:DATA,WEBMVC... 为了便于行文,这里把bean和bean工厂统称为bean。bean英文的意思是豆子。为了符合它的实际作用,本人把bean翻译为“缓存对象实例”,但......
  • spring操作数据库
    xml版程序结构配置文件dbUtil-阿帕奇提供操作数据库的插件核心类:QueryRunner.query()查询.update()增删改<dependencies><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spri......
  • Spring Cloud微服务项目聚合Swagger文档
            在微服务架构中,每个服务通常都有自己独立的API文档。为了方便管理和查看所有服务的接口文档,我们需要将这些文档进行聚合。SpringCloud与Swagger的结合可以帮助我们实现这一目标。本文将介绍如何在SpringCloud微服务项目中聚合Swagger文档,以便于集中......
  • Springboot计算机毕业设计高校实验室管理系统(程序)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,教师,实验课程,课程打卡,实验报告,实验成绩,实验设备,耗材信息,耗材申请开题报告内容一、选题背景与意义1.选题背景随着高校教学科研水平的不断提升,实验......