📌 聊天室项目 - 第一阶段总结
🎯 阶段目标
- 用 Spring Boot 提供 WebSocket(基于 STOMP)后端接口。
- 用 Vue(Vite) 做前端,与后端前后端分离地通信(SockJS + STOMP)。
- 实现:昵称、房间、实时消息收发、前端显示、前后端跨域/代理问题处理。
- 为后续接入数据库持久化、房间隔离、用户上下线、分布式改造打基础。
整体架构
前端(Vue)通过 SockJS 建立到 /chat-websocket 的 STOMP 长连接 → 订阅 /topic/... 接收广播 → 发送消息到 /app/... → 后端 @MessageMapping 接收并处理(可保存 DB)→ 后端广播到对应 /topic/...。
时序图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| sequenceDiagram participant U as 用户(浏览器) participant V as Vue (SockJS + STOMP) participant S as Spring Boot 后端 participant B as STOMP Broker (/topic)
U->>V: 输入昵称,点击连接 V->>S: SockJS 连接 /chat-websocket S-->>V: STOMP CONNECTED
V->>B: 订阅 /topic/chatroom/{roomId} Note right of V: 客户端开始监听房间消息
U->>V: 输入消息,点击发送 V->>S: SEND /app/chat/{roomId}\n{sender, content} S->>S: 保存消息到数据库 S->>B: convertAndSend(/topic/chatroom/{roomId}, message)
B-->>V: 推送 message JSON V-->>U: 页面渲染消息
|
步骤 0 — 环境与依赖
为何要:保证能运行 Spring Boot 与 Vite(Vue)前端。
怎么做:
- 后端:JDK15+,Spring Boot,
spring-boot-starter-web、spring-boot-starter-websocket。
- 前端:Node.js,Vite + Vue3,
sockjs-client、stompjs。
常见坑:Node 版本太低,Lombok 未启用导致编译不过。
步骤 1 — 后端最小实现
目的:快速验证 WebSocket + STOMP 的端到端流程。
1 2 3 4 5 6 7 8 9 10
| @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/chat-websocket").setAllowedOriginPatterns("*").withSockJS(); } }
|
1 2 3
| @MessageMapping("/chat") @SendTo("/topic/messages") public ChatMessage send(ChatMessage message) { return message; }
|
步骤 2 — 前端原生验证
关键点:快速看能否收发消息。
1 2 3 4 5 6 7 8 9
| const socket = new SockJS('/chat-websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, frame => { stompClient.subscribe('/topic/messages', res => { const msg = JSON.parse(res.body); showMessage(msg.sender + ": " + msg.content); }); }); stompClient.send('/app/chat', {}, JSON.stringify({ sender: 'A', content: 'hi' }));
|
步骤 3 — Vue + Vite 前端
迁移到 Vue3 模块化开发。
vite.config.js
1 2 3 4 5
| server: { proxy: { '/chat-websocket': { target: 'http://localhost:8080', ws: true }, '/app': { target: 'http://localhost:8080' }, '/topic': { target: 'http://localhost:8080' } }}
|
步骤 4 — Vue 组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div class="chat-container"> <h2>聊天室</h2> <input v-model="username" placeholder="昵称"/> <button @click="connect">连接</button> <div class="messages"> <div v-for="(msg, idx) in messages" :key="idx"> <b>{{ msg.sender }}</b>: {{ msg.content }} </div> </div> <div v-if="connected"> <input v-model="message" @keyup.enter="sendMessage"/> <button @click="sendMessage">发送</button> </div> </div> </template>
|
步骤 5 — 多房间支持
- 后端
@MessageMapping("/chat/{roomId}")。
- 前端
stompClient.send('/app/chat/' + roomId, ...)。
- 广播路径
/topic/chatroom/{roomId}。
- 使用
SimpMessagingTemplate 可控地发送消息,避免重复。
步骤 6 — 消息持久化
- 使用 MyBatis-Plus + MySQL。
- 实体
Message(roomId, sender, content, type, timestamp)。
- 在 Controller 中:保存消息 →
simpMessagingTemplate.convertAndSend(...) 广播。
步骤 7 — 用户会话管理
- 建立
sessionId -> (username, roomId) 的注册表。
- 在加入时注册,退出时清除。
- 监听
SessionDisconnectEvent,广播“用户退出”系统消息。
调试方法
- 浏览器 Console 日志。
- Network → WS → Frames 检查 STOMP 帧。
- 后端日志
log.info()。
- DB 查询历史消息。
- 检查跨域/代理配置与 STOMP 版本兼容性。
本阶段产出
- Spring Boot WebSocket 聊天室后端。
- Vue 3 前端聊天室 UI。
- 前后端分离开发代理。
- 消息持久化到 MySQL。
- 在线用户管理与系统消息。
下一步建议
- 在线用户列表 API。
- 历史消息分页。
- JWT 登录鉴权。
- Redis Pub/Sub 或 Kafka 实现分布式。
- Docker 部署。