【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.rhkb.cn/news/351110.html

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

相关文章

redis aof写入以及aof重写的源码分析

这里写目录标题 版本aof的面试问题aof正常写入流程aof重写流程 版本 redis&#xff1a;6.2.7 aof的面试问题 最近找工作&#xff0c;面试被问倒了&#xff0c;记录一下 比如redis的aof指令会不会丢失&#xff1f;比如在重写aof的什么新来的操作怎么办&#xff1f; 在重写的…

【云计算】Docker部署Nextcloud网盘并实现随地公网远程访问

配置文件 切换root权限&#xff0c;新建一个nextcloud的文件夹&#xff0c;进入该目录&#xff0c;创建docker-compose.yml [cpslocalhost ~]$ su root Password: 666666 [rootlocalhost cps]# ls Desktop Documents Downloads Music Pictures Public Templates Vide…

【面经总结】Java集合 - Map

Map 概述 Map 架构 HashMap 要点 以 散列(哈希表) 方式存储键值对&#xff0c;访问速度快没有顺序性允许使用空值和空键有两个影响其性能的参数&#xff1a;初始容量和负载因子。 初始容量&#xff1a;哈希表创建时的容量负载因子&#xff1a;其容量自动扩容之前被允许的最大…

CPP多线程

什么是多线程&#xff1f; 多线程是一种允许程序同时运行多个线程的技术。每个线程可以执行不同的任务&#xff0c;这在处理需要并发执行的操作时&#xff08;例如&#xff0c;处理多个客户端的网络服务器&#xff0c;或者图形用户界面应用程序&#xff09;非常有用。多线程能够…

Github 2024-06-13开源项目日报Top10

根据Github Trendings的统计,今日(2024-06-13统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3非开发语言项目2Shell项目1TypeScript项目1Swift项目1PHP项目1Blade项目1JavaScript项目1从零开始构建你喜爱的技术 创建周期:2156…

MySQL数据库管理(一)

目录 1.MySQL数据库管理 1.1 常用的数据类型​编辑 1.2 char和varchar区别 2. 增删改查命令操作 2.1 查看数据库结构 2.2 SQL语言 2.3 创建及删除数据库和表 2.4 管理表中的数据记录 2.5 修改表名和表结构 3.MySQL的6大约束属性 1.MySQL数据库管理 1.1 常用的数据类…

ElementPlus非表单组件ElUpload值更新后校验不消失问题

项目场景&#xff1a; el-form表单中有一个上传组件&#xff0c;有必填校验。 问题描述 先触发表单的必填校验(点击提交按钮)&#xff0c;然后再上传文件&#xff0c;必填校验的提示一直存在&#xff0c;如果再次点击提交&#xff0c;手动触发表单校验&#xff0c;必填校验消…

JavaScript常见面试题(一)

文章目录 1. JavaScript有哪些数据类型&#xff0c;它们的区别&#xff1f;2.数据类型检测的方式有哪些3. 判断数组的方式有哪些4.null和undefined区别5.typeof null 的结果是什么&#xff0c;为什么&#xff1f;6.intanceof 操作符的实现原理及实现7.为什么0.10.2 ! 0.3&…

计算机网络(8) Finite State Machines(有限状态机)

一.建立连接&#xff08;三次握手&#xff09; 建立连接过程中的状态转换如下&#xff1a; 客户端&#xff1a; 发送SYN CLOSED >>>>>>>>>>>>>>SYN SENT(第一次握手) 接收SYNACK发送ACK …

如何看懂SparkUI?

Jobs页面 Stage页面 显示额外的指标和摘要指标&#xff1a; 摘要指标&#xff08;Summary Metrics&#xff09;统计了所有完成的任务的执行行为&#xff0c;包括执行时间、GC时间、输入输出信息等&#xff0c;并提供了最小值&#xff08;Min&#xff09;、第25百分位数&#xf…

HCIA11 网络安全之本地 AAA 配置实验

AAA 提供 Authentication&#xff08;认证&#xff09;、Authorization&#xff08;授权&#xff09;和 Accounting&#xff08;计费&#xff09;三种安全功能。 • 认证&#xff1a;验证用户是否可以获得网络访问权。 • 授权&#xff1a;授权用户可以使用哪些服务。 •…

黑马头条Minio报错non-xml response from server错误的解决方法

今天在写项目的时候&#xff0c;想测试minio上传文件功能是否正常&#xff0c; 但是每次都出现non-xml response from server的错误。 自己也在网上找了很多解决方法&#xff0c;大部分是说用户名和密码的配置问题&#xff0c;但是检查后发现并没有错误。 最后发现是自己的dock…

QT 5.14.2 应用程序打包

我们可以直接通过开发工具预览我们的程序。但是当要把开发好的程序给别人使用的时候&#xff0c;我们就需要把程序打包成可执行的exe&#xff0c;然后把这个exe文件和其他相关的文件一起发给别人&#xff0c;这样别人就可以使用了。 一、生成可独立运行的exe (一)、编译程序的…

图论(一)之概念介绍与图形#matlab

图论&#xff08;一&#xff09;之概念介绍与图形目录 前言 一、图论介绍 二、基本概念 2.1图的概念 2.2图形分类 2.3邻接矩阵 2.3.1无向图 2.3.2有向图 2.3.3有向赋权图 2.4出度&#xff08;Outdegree&#xff09; 2.5入度&#xff08;Indegree&#xff09; 3.四种…

联想电脑 调节屏幕亮度不起使用,按F5,F6,屏幕上的hotkeys进度条是在改变,但是屏幕没有一些作用的处理方法

1、查看驱动是否正常 Win键X &#xff0c;设备管理器 发现似乎挺正常的。 查看原厂驱动&#xff1a;联想电脑管家 这样看来&#xff0c;驱动是没有问题了。 2、看看设置电池模式 其实还是这个电池模式的问题导致。 如果处于养护模式的话&#xff0c;充电只在75%~80%&#x…

【Numpy】一文向您详细介绍 np.round()

【Numpy】一文向您详细介绍 np.round() 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&#xff0c;…

【大数据】计算引擎:Spark核心概念

目录 前言 1.什么是Spark 2.核心概念 2.1.Spark如何拉高计算性能 2.2.RDD 2.3.Stage 3.运行流程 前言 本文是作者大数据系列中的一文&#xff0c;专栏地址&#xff1a; https://blog.csdn.net/joker_zjn/category_12631789.html?spm1001.2014.3001.5482 该系列会成体…

【SpringCloud学习笔记】RabbitMQ(上)

1. RabbitMQ简介 官网地址&#xff1a;https://www.rabbitmq.com/ 2. 安装方式 安装前置准备&#xff1a; 此处基于Linux平台 Docker进行安装&#xff0c;前置准备如下&#xff1a; Linux云服务器 / 虚拟机Docker环境 安装命令&#xff1a; docker run \-e RABBITMQ_DEFAU…

TCP与UDP案例

udp不会做拆分整合什么的 多大就是多大

【日记】第一次养植物,没什么经验……(781 字)

正文 前两天梦见灵送的几盆植物全都死掉了。梦里好伤心。醒来与她说这件事&#xff0c;她宽慰我说&#xff0c;梦都是反着的&#xff0c;肯定能活得很好的。于是忽然记起昨天给植物换水时&#xff0c;文竹的根居然从花盆底部伸吊了出来&#xff0c;以前都没有这种情况来着&…