98 lines
2.5 KiB
Markdown
98 lines
2.5 KiB
Markdown
# 04 - 消息协议与消息分发(统一 Message 模型)
|
||
|
||
## 功能目标
|
||
- 定义统一消息格式(便于扩展与兼容)。
|
||
- 服务端负责房间维度的消息广播/转发。
|
||
- 前端按 `type` 分发渲染与业务处理。
|
||
|
||
## 协议定义
|
||
### 基础消息格式
|
||
```json
|
||
{
|
||
"type": "TEXT | FILE | IMAGE | SYSTEM | CHUNK",
|
||
"senderId": "uuid",
|
||
"senderName": "用户昵称",
|
||
"timestamp": 1706345600000,
|
||
"payload": {}
|
||
}
|
||
```
|
||
|
||
### 文本消息(TEXT)
|
||
```json
|
||
{
|
||
"type": "TEXT",
|
||
"senderId": "uuid",
|
||
"senderName": "用户A",
|
||
"timestamp": 1706345600000,
|
||
"payload": {
|
||
"content": "要传输的文本内容",
|
||
"isChunk": false,
|
||
"chunkIndex": 0,
|
||
"totalChunks": 1
|
||
}
|
||
}
|
||
```
|
||
|
||
### 文件元数据(FILE)
|
||
```json
|
||
{
|
||
"type": "FILE",
|
||
"senderId": "uuid",
|
||
"senderName": "用户A",
|
||
"timestamp": 1706345600000,
|
||
"payload": {
|
||
"fileId": "uuid",
|
||
"fileName": "document.pdf",
|
||
"fileSize": 2621440,
|
||
"mimeType": "application/pdf",
|
||
"totalChunks": 10
|
||
}
|
||
}
|
||
```
|
||
|
||
### 文件分片(CHUNK)
|
||
```json
|
||
{
|
||
"type": "CHUNK",
|
||
"senderId": "uuid",
|
||
"payload": {
|
||
"fileId": "uuid",
|
||
"chunkIndex": 0,
|
||
"data": "base64EncodedChunkData"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 系统消息(SYSTEM)
|
||
```json
|
||
{
|
||
"type": "SYSTEM",
|
||
"payload": {
|
||
"event": "USER_JOIN | USER_LEAVE | ERROR",
|
||
"message": "xxx 加入了房间",
|
||
"userList": [{"id": "uuid", "name": "用户A"}]
|
||
}
|
||
}
|
||
```
|
||
|
||
## 前端分发(Vue)
|
||
- **入口**:`RoomView` 的 `handleMessage(msg)` 或等价逻辑。
|
||
- **分发规则(示例)**
|
||
- `SYSTEM`:更新 `userList`,并向消息列表追加系统提示。
|
||
- `TEXT`:追加文本消息(区分 me/other)。
|
||
- `FILE`:追加文件卡片(显示名称、大小、下载按钮、进度)。
|
||
- `CHUNK`:写入文件缓存并更新进度;完成后合并为 Blob。
|
||
|
||
## 后端分发(Spring Boot)
|
||
- **控制器**:`WebSocketController`
|
||
- `/message`:广播常规消息到 `/topic/room/{roomCode}`
|
||
- `/file/chunk`:转发分片到文件通道或同房间通道
|
||
- **补齐与校验(建议)**
|
||
- 服务端补齐 `timestamp`,必要时校验 `type/payload` 的字段完整性、大小限制与频率限制。
|
||
|
||
## 边界与注意点
|
||
- **通道设计一致性**:若采用“文件独立 topic”,前端需额外 subscribe;若统一走房间 topic,需在 payload 内携带 fileId 并做路由分发。
|
||
- **大消息**:避免一次性发送超大 payload;统一走分片策略。
|
||
- **安全**:前端渲染文本必须转义,禁止把用户内容当 HTML 渲染。
|
||
|