【SpringBoot】SpringBoot:构建实时聊天应用

文章目录

      • 引言
      • 项目初始化
        • 添加依赖
      • 配置WebSocket
        • 创建WebSocket配置类
        • 创建WebSocket处理器
      • 创建前端页面
        • 创建聊天页面
      • 测试与部署
        • 示例:编写单元测试
      • 部署
      • 扩展功能
        • 用户身份验证
        • 消息持久化
        • 群组聊天
      • 结论

在这里插入图片描述

引言

随着实时通信技术的快速发展,聊天应用在现代Web和移动应用中变得越来越重要。从简单的客服聊天到复杂的团队协作工具,实时通信都扮演着关键角色。SpringBoot结合WebSocket技术,能够高效地构建实时聊天应用。本文将详细介绍如何使用SpringBoot和WebSocket来构建一个实时聊天应用,并讨论相关的最佳实践。

项目初始化

首先,我们需要创建一个SpringBoot项目,并添加WebSocket相关的依赖项。可以通过Spring Initializr快速生成项目。

添加依赖

pom.xml中添加以下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

配置WebSocket

创建WebSocket配置类

创建一个配置类,用于配置WebSocket连接。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new ChatWebSocketHandler(), "/chat").setAllowedOrigins("*");}
}
创建WebSocket处理器

创建一个处理WebSocket消息的处理器类。

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;import java.util.ArrayList;
import java.util.List;public class ChatWebSocketHandler extends TextWebSocketHandler {private List<WebSocketSession> sessions = new ArrayList<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);}@Overridepublic void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {for (WebSocketSession webSocketSession : sessions) {webSocketSession.sendMessage(new TextMessage(message.getPayload()));}}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {sessions.remove(session);}
}

创建前端页面

创建聊天页面

使用Thymeleaf创建一个简单的聊天页面。在src/main/resources/templates目录下创建一个chat.html文件:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Chat Room</title><script>var socket;function connect() {socket = new WebSocket("ws://localhost:8080/chat");socket.onmessage = function(event) {var messages = document.getElementById("messages");var message = document.createElement("p");message.appendChild(document.createTextNode(event.data));messages.appendChild(message);};}function sendMessage() {var input = document.getElementById("messageInput");socket.send(input.value);input.value = '';}</script>
</head>
<body onload="connect()"><h1>Chat Room</h1><div id="messages"></div><input type="text" id="messageInput" placeholder="Enter message" onkeydown="if (event.key === 'Enter') sendMessage()"/><button onclick="sendMessage()">Send</button>
</body>
</html>

测试与部署

在完成实时聊天功能的开发后,应该进行充分的测试,确保所有功能都能正常工作。可以使用JUnit和MockMVC进行单元测试和集成测试。

示例:编写单元测试
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;@SpringBootTest
@AutoConfigureMockMvc
public class ChatApplicationTests {@Autowiredprivate MockMvc mockMvc;@Testpublic void testChatPage() throws Exception {mockMvc.perform(get("/chat")).andExpect(status().isOk()).andExpect(content().string(org.hamcrest.Matchers.containsString("Chat Room")));}
}

通过这种方式,可以确保应用的各个部分在开发过程中得到充分的测试,减少上线后的问题。

部署

SpringBoot应用可以打包成可执行的JAR文件,方便部署。通过mvn package命令,可以生成一个包含所有依赖的JAR文件。

mvn package
java -jar target/demo-0.0.1-SNAPSHOT.jar

这种打包方式使得SpringBoot应用的部署变得非常简单,不再需要复杂的服务器配置。

扩展功能

在基本的实时聊天功能基础上,可以进一步扩展功能,使其更加完善和实用。例如:

  • 用户身份验证:可以集成Spring Security,实现用户登录和身份验证。
  • 消息持久化:将聊天消息存储到数据库中,以便后续查询和分析。
  • 群组聊天:实现多个聊天室,每个聊天室有独立的聊天内容。
  • 消息通知:集成WebSocket通知功能,当有新消息时,向用户发送通知。
用户身份验证

可以使用Spring Security实现用户身份验证。在前面的示例中,我们已经配置了Spring Security。在此基础上,可以实现用户登录和权限控制。

消息持久化

为了实现消息持久化,可以将聊天消息存储到数据库中。首先,创建一个消息实体类和消息存储库:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;@Entity
public class ChatMessage {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String sender;private String content;// getters and setters
}
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;@Repository
public interface ChatMessageRepository extends JpaRepository<ChatMessage, Long> {
}

然后,在WebSocket处理器中保存消息:

import org.springframework.beans.factory.annotation.Autowired;public class ChatWebSocketHandler extends TextWebSocketHandler {@Autowiredprivate ChatMessageRepository chatMessageRepository;@Overridepublic void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {ChatMessage chatMessage = new ChatMessage();chatMessage.setSender(session.getId());chatMessage.setContent(message.getPayload());chatMessageRepository.save(chatMessage);for (WebSocketSession webSocketSession : sessions) {webSocketSession.sendMessage(new TextMessage(message.getPayload()));}}
}
群组聊天

为了实现群组聊天,可以为每个群组创建一个独立的WebSocket端点。用户可以选择加入不同的群组聊天。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new ChatWebSocketHandler(), "/chat/{group}").setAllowedOrigins("*");}
}

结论

通过本文的介绍,我们了解了如何使用SpringBoot和WebSocket实现实时聊天应用。从项目初始化、WebSocket配置、前端页面创建,到消息持久化和功能扩展,SpringBoot提供了一系列强大的工具和框架,帮助开发者高效地构建现代化的实时聊天应用。希望这篇文章能够帮助开发者更好地理解和使用SpringBoot,在实际项目中实现实时通信的目标。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Luma AI如何注册:文生视频领域的新星

文章目录 Luma AI如何注册&#xff1a;文生视频领域的新星一、Luma 注册方式二、Luma 的效果三、Luma 的优势四、Luma 的功能总结 Luma AI如何注册&#xff1a;文生视频领域的新星 近年来&#xff0c;Luma AI 凭借其在文生视频领域的创新技术&#xff0c;逐渐成为行业的新星。…

MySQL基础——多表查询和事务

目录 1多表关系 2多表查询概述 3连接查询 3.1内连接 3.2左外连接 3.3右外连接 3.4自连接 4联合查询 5子查询 5.1标量子查询(子查询结果为单个值) 5.2列子查询(子查询结果为一列) 5.3行子查询(子查询结果为一行) 5.4表子查询(子查询结果为多行多列) 6事务简介和操…

vulnhub靶场-xxe打靶教程

目录 靶机导入 信息收集 发现IP 端口扫描 目录扫描 漏洞利用 靶机下载地址&#xff1a;XXE Lab: 1 ~ VulnHub 靶机导入 导入虚拟机 开启虚拟机 信息收集 发现IP arp-scan -l 发现靶机IP是192.168.202.150 端口扫描 使用nmap进行扫描 nmap -sS -A 192.168.202.150 …

EasyRecovery2024数据恢复神器#电脑必备良品

EasyRecovery数据恢复软件&#xff0c;让你的数据重见天日&#xff01; 大家好&#xff01;今天我要给大家种草一个非常实用的软件——EasyRecovery数据恢复软件&#xff01;你是不是也曾经遇到过不小心删除了重要的文件&#xff0c;或者电脑突然崩溃导致数据丢失的尴尬情况呢&…

初识PHP

一、格式 每行以分号结尾 <?phpecho hello; ?>二、echo函数和print函数 作用&#xff1a;两个函数都是输出内容到页面中&#xff0c;多用于代码调试。 <?php echo "<h1 styletext-align: center;>test</h1>"; print "<h1 stylet…

【vue3中使用$refs】

在使用uniapp官网里的uni-popup弹出层组件时&#xff0c;要将vue2转换成vue3,&#xff0c;这里遇到了一个问题&#xff1a;vue2可以通过this访问到绑定的ref&#xff0c;但是vue3没有了this,应该怎么办呢&#xff1f; 解决方法&#xff1a; !

Footer组件在home 、search 显示,在登录、注册隐藏

footer组件显示与隐藏 我们可以根据组件身上的$route获取当前路由的信息&#xff0c;通过路由路径判断Footer显示与隐藏。配置的路由的时候&#xff0c;可以给路由添加路由元信息【meta】&#xff0c;路由需要配置对象&#xff0c;它的key不能瞎写、胡写、乱写 <template&…

基于 Nginx Ingress + 云效 AppStack 实现灰度发布

作者&#xff1a;子丑 场景简介 灰度发布是降低生产部署风险&#xff0c;提升线上服务稳定性的重要手段&#xff0c;这在当前快速迭代的软件研发中尤为重要。相对于 K8s 默认的滚动部署或者简单的 Pod 分批&#xff0c;基于流量特征的灰度发布验证更精准&#xff0c;风险更低…

将qt的子程序窗口嵌入qt的主进程主窗口中(第二种方式)

上一篇文章,存在失去焦点问题,分析可能原因是直接将子进程的窗口句柄封装到QWindow对象中之后,窗口的键盘事件可能就qt自己处理,但是目前没有搞清楚怎么处理的. 下面这种方式也类似第一种方式,不同点在于处理窗口句柄的方式. 通过自定义一个QWindow的一个子类,在子类中通过wi…

TypeScript中的Symbol,确实唯一。。。

Symbol 目录 Symbol 目录自动推断symbol unique symbol区别 自动推断 let命令声明的变量&#xff0c;推断类型为 symbol。// let定义symbol推断为symbol let sym Symbol(); //symbol但是&#xff0c;const命令声明的变量&#xff0c;如果赋值为另一个 symbol 类型的变量&…

解释双向队列(Deque)的概念,Java 中的 ArrayDeque 和 LinkedList 作为 Deque 的实现,它们各自有什么优缺点?

双向队列&#xff08;Deque&#xff0c;全称为 Double Ended Queue&#xff09;是一种具有队列和栈特性的数据结构&#xff0c;允许在两端进行元素的添加和移除操作。这意味着你可以在队列的前端&#xff08;头部&#xff09;或后端&#xff08;尾部&#xff09;进行入队&#…

从 Acme.Sh V3.0 说说 ZeroSSL

熟悉明月的都知道&#xff0c;明月一直都在使用 acme.sh 作为服务器端申请、部署、续期免费 SSL 证书的主要工具&#xff0c;今天在帮一个站长申请 SSL 证书的时候发现 acme.sh v3.0 开始默认的免费 SSL 证书变更为&#xff1a;ZeroSSL 了&#xff0c;这个 ZeroSSL 其实跟明月一…

在 C++ 中使用不同平台的时间函数及比较

在 C 编程中&#xff0c;时间函数的选择对于性能测量、任务调度和时间戳记录至关重要。不同的操作系统提供了不同的时间函数&#xff0c;同时在同一个平台上&#xff0c;也可能有多种不同的时间函数可供选择。本文将介绍在 C 中常用的时间函数&#xff0c;并比较它们在不同平台…

通俗范畴论2 有向图与准范畴

退一步海阔天空&#xff0c;在正式进入范畴论之前&#xff0c;我们可以重新审视一下我们是如何认识世界的&#xff0c;有了这个对人类认识世界过程的底层理解&#xff0c;可以帮助我们更好地理解范畴论。 对于人类认识世界&#xff0c;最神奇的一点就是这个世界居然是可以认识…

map文件分析

以下是一个具体的map文件示例&#xff0c;并附上详细的描述&#xff0c;帮助你更好地理解如何读取和分析map文件&#xff1a; 示例map文件 Memory ConfigurationName Origin Length Attributes FLASH 0x08000000 0x0…

初识docker插件

文章目录 一、Docker插件概述二、Docker插件的优势三、Docker插件的使用例子1. 安装Docker插件2. 启用Docker插件3. 创建卷并使用 四、常用的Docker插件五、总结 Docker插件&#xff08;Docker Plugin&#xff09;是Docker扩展功能的一种重要方式&#xff0c;它允许用户为Docke…

Elasticsearch 认证模拟题 - 22

一、题目 索引 task 索引中文档的 fielda 字段内容包括了 hello & world&#xff0c;索引后&#xff0c;要求使用 match_phrase query 查询 hello & world 或者 hello and world 都能匹配该文档 1.1 考点 分词器 1.2 答案 # 创建符合条件的 task 索引&#xff0c;…

C++之 delete删除拷贝构造函数和拷贝赋值运算符

在 C 中&#xff0c;删除拷贝构造函数和拷贝赋值运算符是一种常见的方法&#xff0c;用于防止对象的拷贝和赋值。这在某些情况下是必要的&#xff0c;例如当类管理资源&#xff08;如线程、文件句柄或网络连接&#xff09;时&#xff0c;以确保资源的唯一性和避免潜在的资源泄漏…

算法人生(22):从“生成对抗网络”看“逆商提升”

​ 在图像生成与编辑、音频合成、视频生成领域里&#xff0c;有一个非常重要的深度学习方法——生成对抗网络&#xff08;简称GANs&#xff09;&#xff0c;它是由两个神经网络组成的模型&#xff0c;分别为生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discr…

【Linux】I/O多路复用

文章目录 I/O多路复用select()select()缺点 poll()poll()缺点 epoll()LT(水平触发模式)ET(边缘触发模式)具体函数 I/O多路复用 多进程和多线程实现并发会消耗大量的资源&#xff0c;主进程/线程用于监听和接受连接&#xff0c;再创建多个子进程/子线程来完成与连接的各个客户端…