chatroom_stage2_summary


📌 聊天室项目 - 第一阶段总结

🎯 阶段目标

  • 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-webspring-boot-starter-websocket
  • 前端:Node.js,Vite + Vue3,sockjs-clientstompjs

常见坑: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,广播“用户退出”系统消息。

调试方法

  1. 浏览器 Console 日志。
  2. Network → WS → Frames 检查 STOMP 帧。
  3. 后端日志 log.info()
  4. DB 查询历史消息。
  5. 检查跨域/代理配置与 STOMP 版本兼容性。

本阶段产出

  • Spring Boot WebSocket 聊天室后端。
  • Vue 3 前端聊天室 UI。
  • 前后端分离开发代理。
  • 消息持久化到 MySQL。
  • 在线用户管理与系统消息。

下一步建议

  1. 在线用户列表 API。
  2. 历史消息分页。
  3. JWT 登录鉴权。
  4. Redis Pub/Sub 或 Kafka 实现分布式。
  5. Docker 部署。


文章作者: Benjamin Li
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Benjamin Li !
  目录