news 2026/4/25 0:38:13

从零构建SpringBoot+WebSocket即时通讯系统:手把手实战教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零构建SpringBoot+WebSocket即时通讯系统:手把手实战教程

1. 为什么选择SpringBoot+WebSocket构建即时通讯系统?

即时通讯系统已经成为现代互联网应用的标配功能,从社交软件到在线客服,实时消息交互的需求无处不在。传统HTTP协议由于"一问一答"的通信模式,无法满足实时双向通信的需求。而WebSocket协议的出现完美解决了这个问题。

SpringBoot作为Java生态中最流行的框架之一,与WebSocket的结合堪称绝配。我实际项目中采用这种组合已经开发过3个即时通讯系统,最大的优势在于:

  • 开发效率高:SpringBoot的自动配置让WebSocket集成变得极其简单
  • 性能出色:单机可支持数千并发连接
  • 扩展性强:轻松整合MySQL、Redis等存储方案
  • 维护成本低:Spring生态完善的文档和社区支持

2. 开发环境准备

2.1 基础工具安装

工欲善其事必先利其器,我们先准备好开发环境。我的推荐配置是:

  • JDK 17:长期支持版本,性能优化更好
  • IntelliJ IDEA 2023+:社区版就足够用
  • MySQL 8.0:比5.7性能提升明显
  • Postman:接口测试利器
  • Node.js:前端开发环境
# 检查Java环境 java -version # 检查MySQL版本 mysql --version

2.2 创建SpringBoot项目

在IDEA中新建项目:

  1. 选择Spring Initializr
  2. 添加依赖:Spring Web、WebSocket、MyBatis、MySQL Driver
  3. 项目命名:chat-system
  4. 打包方式选择Jar

第一次启动可能会遇到端口冲突,我在Windows上经常碰到这个问题。解决方法:

# application.properties server.port=8081

3. WebSocket核心配置

3.1 WebSocket协议基础

WebSocket协议最大的特点是:

  • 全双工通信
  • 低延迟
  • 长连接
  • 轻量级头部

与HTTP对比:

特性WebSocketHTTP
连接方式长连接短连接
通信方向双向单向
数据格式二进制/文本文本
头部大小2-10字节800+字节

3.2 SpringBoot集成WebSocket

创建WebSocket配置类:

@Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/ws") .setAllowedOrigins("*") .addInterceptors(new HttpSessionHandshakeInterceptor()); } @Bean public WebSocketHandler myHandler() { return new MyWebSocketHandler(); } }

处理类继承TextWebSocketHandler:

public class MyWebSocketHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) { // 连接建立逻辑 } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) { // 处理消息 } }

4. 数据库设计与实现

4.1 核心表结构设计

即时通讯系统通常需要这几张表:

  1. 用户表(user):存储用户基本信息
  2. 好友关系表(friend):记录用户好友关系
  3. 会话表(session):聊天会话信息
  4. 消息表(message):存储聊天记录
CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(100) NOT NULL, `avatar` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`) ); CREATE TABLE `friend` ( `user_id` bigint NOT NULL, `friend_id` bigint NOT NULL, PRIMARY KEY (`user_id`,`friend_id`) ); CREATE TABLE `session` ( `id` bigint NOT NULL AUTO_INCREMENT, `type` tinyint NOT NULL COMMENT '1-单聊 2-群聊', `create_time` datetime NOT NULL, PRIMARY KEY (`id`) ); CREATE TABLE `message` ( `id` bigint NOT NULL AUTO_INCREMENT, `session_id` bigint NOT NULL, `sender_id` bigint NOT NULL, `content` text NOT NULL, `send_time` datetime NOT NULL, PRIMARY KEY (`id`), KEY `idx_session` (`session_id`) );

4.2 MyBatis整合与优化

配置数据源和MyBatis:

spring: datasource: url: jdbc:mysql://localhost:3306/chat_db?useSSL=false username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml configuration: map-underscore-to-camel-case: true

消息Mapper示例:

@Mapper public interface MessageMapper { @Insert("INSERT INTO message VALUES(null,#{sessionId},#{senderId},#{content},NOW())") int insert(Message message); @Select("SELECT * FROM message WHERE session_id=#{sessionId} ORDER BY send_time DESC LIMIT 100") List<Message> selectBySessionId(long sessionId); }

5. 核心功能实现

5.1 用户认证与会话管理

WebSocket连接需要先经过HTTP认证:

public class AuthInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) { // 从请求参数获取token String token = ((ServletServerHttpRequest) request).getServletRequest() .getParameter("token"); // 验证token逻辑 User user = authService.validateToken(token); if(user == null) { return false; } attributes.put("user", user); return true; } }

5.2 消息收发实现

消息处理核心逻辑:

public class MessageHandler extends TextWebSocketHandler { private final OnlineUserManager onlineUserManager; private final MessageService messageService; @Override protected void handleTextMessage(WebSocketSession session, TextMessage textMessage) { // 解析消息 MessageDTO message = JSON.parseObject(textMessage.getPayload(), MessageDTO.class); // 存储消息 messageService.save(message); // 转发给目标用户 WebSocketSession targetSession = onlineUserManager.getSession( message.getReceiverId()); if(targetSession != null && targetSession.isOpen()) { targetSession.sendMessage(textMessage); } } }

5.3 在线状态管理

使用ConcurrentHashMap维护在线用户:

@Component public class OnlineUserManager { private final Map<Long, WebSocketSession> onlineUsers = new ConcurrentHashMap<>(); public void online(Long userId, WebSocketSession session) { onlineUsers.put(userId, session); } public void offline(Long userId) { onlineUsers.remove(userId); } public WebSocketSession getSession(Long userId) { return onlineUsers.get(userId); } }

6. 前端实现关键点

6.1 WebSocket连接建立

前端WebSocket连接代码:

const socket = new WebSocket(`ws://localhost:8080/ws?token=${localStorage.token}`); socket.onopen = () => { console.log('连接已建立'); }; socket.onmessage = (event) => { const message = JSON.parse(event.data); // 处理消息 }; socket.onclose = () => { console.log('连接已关闭'); };

6.2 消息列表渲染

使用Vue实现消息列表:

<div v-for="message in messages" :key="message.id" :class="{'self': message.isSelf}"> <div class="avatar">{{message.senderName[0]}}</div> <div class="content">{{message.content}}</div> </div>

7. 部署与优化

7.1 Linux服务器部署

推荐使用Nginx反向代理:

server { listen 80; server_name chat.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }

启动SpringBoot应用:

nohup java -jar chat-system.jar --spring.profiles.active=prod &

7.2 性能优化建议

  1. 连接数优化

    • 调整Linux文件描述符限制
    • 使用Netty替代Tomcat容器
  2. 消息存储优化

    • 热数据放Redis
    • 冷数据定期归档
  3. 集群部署

    spring: redis: host: redis-cluster

8. 常见问题解决方案

问题1:WebSocket连接频繁断开
解决:添加心跳检测机制

// 服务端配置 @Bean public ServletServerContainerFactoryBean createWebSocketContainer() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); container.setMaxSessionIdleTimeout(300000L); // 5分钟 return container; }

问题2:消息乱序
解决:客户端添加消息序号和服务端队列处理

问题3:高并发下性能下降
解决

  • 使用消息队列削峰
  • 采用分布式WebSocket方案

实际开发中我还遇到过Nginx配置不当导致WebSocket连接失败的问题,排查后发现是缺少Upgrade头配置。这个坑花了我半天时间才解决,特别提醒大家注意。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 0:33:29

别只当摄像头用!用MaixPy IDE玩转MaixBit的3个创意小项目

别只当摄像头用&#xff01;用MaixPy IDE玩转MaixBit的3个创意小项目 当你第一次点亮MaixBit开发板&#xff0c;看到摄像头画面在MaixPy IDE的帧缓冲区里跳动时&#xff0c;那种兴奋感我至今记得。但很快你就会发现——如果只是把这块搭载K210芯片的硬件当作普通摄像头&#xf…

作者头像 李华
网站建设 2026/4/25 0:32:36

Helix 511工业级无风扇嵌入式计算机详解

1. Helix 511工业级无风扇嵌入式计算机概述在工业自动化和边缘计算领域&#xff0c;设备需要具备稳定、可靠且适应恶劣环境的特性。OnLogic推出的Helix 511正是为这类场景设计的工业级无风扇嵌入式计算机。它搭载了Intel第12代Alder Lake处理器&#xff0c;从入门级的Celeron 7…

作者头像 李华
网站建设 2026/4/25 0:30:10

Amlogic S9xxx盒子无线网卡终极适配指南:5分钟搞定RTL8822CS驱动

Amlogic S9xxx盒子无线网卡终极适配指南&#xff1a;5分钟搞定RTL8822CS驱动 【免费下载链接】amlogic-s9xxx-armbian Supports running Armbian on Amlogic, Allwinner, and Rockchip devices. Support a311d, s922x, s905x3, s905x2, s912, s905d, s905x, s905w, s905, s905l…

作者头像 李华