上传文件至 /

This commit is contained in:
西街长安 2025-10-12 20:36:18 +08:00
parent 50d2700dba
commit 6717e40659
5 changed files with 694 additions and 0 deletions

View File

@ -1079,6 +1079,15 @@
<mxCell id="LlkoEB-2TC3n23V2uSJG-11" value="角色ID" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="370" y="1890" width="90" height="50" as="geometry" />
</mxCell>
<mxCell id="LlkoEB-2TC3n23V2uSJG-12" value="昵称" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="240" y="300" width="90" height="50" as="geometry" />
</mxCell>
<mxCell id="LlkoEB-2TC3n23V2uSJG-13" value="" style="endArrow=none;html=1;rounded=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="LqGEv66xggxL4AquUroI-1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="280" y="300" as="sourcePoint" />
<mxPoint x="330" y="250" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>

View File

@ -0,0 +1,141 @@
# IM 系统消息存储与推送策略文档
## 1. 概述
本策略文档定义了 **消息在系统中的存储、读取和推送流程**,目标是:
- 保证 **消息实时性**
- 支持 **离线消息存储与同步**
- 支持 **多端登录同步**
- 支持 **单聊、群聊及系统消息**
------
## 2. 消息存储策略
### 2.1 消息表设计
表结构参考前期设计:
| 表名 | 作用 |
| ------------ | ------------------------------------------------------------ |
| Messages | 存储所有聊天消息(单聊/群聊) |
| Conversation | 缓存用户最近会话信息last_message_id, target_id, unread_count |
| Files | 附件 / 图片 / 语音存储URL |
------
### 2.2 消息存储规则
1. **单聊消息**
- 写入 `Messages`
- 更新发送者和接收者 `Conversation`
- 更新 `UnreadCount`
2. **群聊消息**
- 写入 `Messages`
- 更新群成员对应的 `Conversation`except 发送者)
- 更新每个成员的 `UnreadCount`
3. **文件消息**
- 文件存储到对象存储OSS/S3/MinIO
- `Messages.Content` 存文件 URL + metadata
4. **消息撤回**
- 消息允许撤回时,修改 `message.status = 1
- 更新 `Conversation.LastMessageId`(如撤回的是最后一条消息)
------
## 3. 消息推送策略
### 3.1 推送原则
- **实时性**:在线用户立即通过 WebSocket 推送
- **可靠性**:离线用户存储消息,登录时同步
- **顺序保证**:消息按 `timestamp``messageId` 顺序发送
- **幂等性**:客户端可根据 `messageId` 去重
------
### 3.2 单聊推送流程
1. 发送者通过 WebSocket 或 HTTP API 发送消息
2. 服务端写入 `Messages`
3. 查询接收者是否在线
- **在线**:通过 WebSocket 推送
- **离线**:存储到 Redis 或 `Conversation.UnreadCount`
4. 接收者收到消息后发送 `MESSAGE_ACK`
5. //暂不要求:更新消息状态(已送达 / 已读)
------
### 3.3 群聊推送流程
1. 发送者发送群消息
2. 服务端写入 `Message`s 表
3. 查询群成员列表(`GroupMember` 表)
4. 遍历成员:
- **在线成员**WebSocket 推送
- **离线成员**:增加 `UnreadCount`,保存在 Redis/数据库
5. //暂不要求:接收者回 ACK 后更新 `message_receipt`(已读)
------
### 3.4 离线消息处理
- 离线消息存储位置:
1. 数据库 `Messages` 表(长期保存)
2. Redis 缓存(短期加速推送)
- 客户端上线时:
1. 请求 `/syncMessages` 接口
2. 返回未读消息 + 未读计数
- 消息同步完成后清除缓存或更新状态
------
### 3.5 多端同步策略
- 每个设备维护独立的 `deviceId`
- WebSocket 推送时:
- 排除发送设备
- 推送给同账号其他设备
- //暂不要求:消息回执:
- 每端发送 ACK
- 服务端更新 `Voncers``message_receipt`
------
## 4. 消息可靠性保障
| 场景 | 解决方案 |
| ------------------ | ---------------------------------- |
| 消息丢失 | 发送端生成 `requestId`,服务端去重 |
| 消息顺序错乱 | 按 `messageId``timestamp` 排序 |
| WebSocket 异常断开 | 客户端重连后同步离线消息 |
| 群聊大消息量 | 异步推送 + 批量 ACK |
------
## 5. //暂不要求:高性能优化策略
1. **消息表索引**`(chat_type, to_id, created_at)`
2. **会话表缓存**`conversation` 表避免全表查询
3. **Redis 缓存**:用户在线状态、未读消息数
4. **分表/分库**:按月或按用户分表
5. **异步推送队列**:消息通过 MQKafka/RabbitMQ推送保证高并发
------
## 6. 消息撤回与删除策略
1. **撤回条件**:超时限制( 2 分钟内可撤回)
2. **撤回操作**
- 更新 `message.status = 1`
- 更新 `Conversation.LastMessageId`
- 推送撤回事件到在线用户
------
## 7. 系统消息与通知策略
- 系统消息(好友申请、群邀请、公告)走 **同样的消息推送流程**
- 保留在 `Notification`
- 支持离线同步

View File

@ -0,0 +1,115 @@
# IM 系统鉴权与 Token 安全规范文档
## 1. 概述
本规范用于确保系统用户身份验证、消息安全和多端同步安全。
鉴权体系采用 **TokenJWT 或自定义) + HTTPS/WebSocket** 方式。
------
## 2. 鉴权方式选择
| 方法 |
| -------------------------------------- |
| JWTJSON Web Token+ Redis黑名单机制 |
------
## 3. Token 生成规则
### 3.1 Token 内容结构JWT 示例)
```
{
"userId": 1001, // 用户ID
"iat": 1700000000, // 签发时间Unix时间戳
"exp": 1700003600, // 过期时间
"deviceId": "uuid-xxxx", // 设备ID用于多端区分
"role": "user" // 角色
}
```
- **签名算法**HMAC-SHA256 或 RSA
- **签名秘钥**:服务端统一管理,不暴露给客户端
------
### 3.2 Token 生成流程
1. 用户登录(用户名/密码)
2. 验证用户名与密码正确
3. 生成 Token写入 Redis可选
4. 返回 Token 给客户端
**响应示例**
```
{
"code": 0,
"message": "登录成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
```
------
## 4. Token 使用
### 4.1 HTTP 接口鉴权
- 客户端请求带上 Header
```
Authorization: Bearer <token>
```
- 后端解析 Token
1. 校验签名
2. 校验 exp 是否过期
3. 校验 Redis 黑名单(可选)
- 不通过返回 401 / code 1006
------
### 4.2 WebSocket 鉴权
- 建立连接时通过 Query 或 Header 传 Token
```
ws://example.com/ws?token=xxxx&deviceId=uuid-001
```
- 握手阶段:
1. 服务器验证 Token
2. 成功返回 AUTH_SUCCESS
3. 失败返回 AUTH_FAIL 并关闭连接
------
## 5. Token 过期策略
| 类型 | 建议值 | 说明 |
| ------------------ | ---------------------- | ---------------------------------------- |
| 短期 Token | 30 分钟 ~ 1 小时 | 防止长时间泄露 |
| 长期 Refresh Token | 7 ~ 30 天 | 用于获取新 Token安全性高 |
| WebSocket 长连接 | Token 与短期有效期一致 | 客户端定期刷新 Token心跳或重连时验证 |
### 5.1 Token 刷新流程
1. 客户端 Token 快过期时,调用刷新接口
2. 服务端验证 Refresh Token
3. 返回新 Token更新 Redis / 黑名单
------
## 6. 多端登录处理
- **每个设备对应一个 deviceId**
- Token 中绑定 deviceId
- 多端策略:
1. **允许多端同时登录**:每端单独维护 Token
2. **限制单端登录**:新登录覆盖旧设备 Token
3. **设备列表管理**:可查看在线设备并强制下线

View File

@ -0,0 +1,285 @@
# 📘 WebSocket 通讯协议设计文档
## 1. 概述
本协议用于实现 **即时聊天IM系统的实时消息传输**
客户端通过 WebSocket 连接后与服务器保持长连接,实现消息推送、状态同步、群聊与单聊。
**支持功能**
- 用户登录鉴权
- 单聊消息发送/接收
- 群聊消息发送/接收
- 消息撤回、已读回执
- 心跳保活与断线重连
- 系统通知(好友请求、群邀请)
------
## 2. 消息传输格式
### 2.1 基础消息结构JSON
```
{
"type": "MESSAGE_TYPE",
"requestId": "string", // 客户端生成的请求ID便于幂等
"from": 1001, // 发送者ID
"to": 1002, // 接收者ID单聊或群ID群聊
"chatType": "single", // "single" | "group"
"contentType": "text", // "text" | "image" | "file" | "voice" | "system"
"content": "消息内容或文件URL",
"timestamp": 1700000000 // Unix时间戳
}
```
------
### 2.2 常用 type 枚举
| type | 说明 |
| -------------- | ------------------------- |
| AUTH | 握手鉴权 |
| HEARTBEAT | 心跳保活 |
| MESSAGE | 普通聊天消息(单聊/群聊) |
| MESSAGE_ACK | 消息已读/送达回执 |
| MESSAGE_RECALL | 消息撤回 |
| FRIEND_REQUEST | 好友申请通知 |
| GROUP_INVITE | 群邀请通知 |
| SYSTEM_NOTICE | 系统公告/通知 |
| ERROR | 错误消息 |
------
## 3. 握手与鉴权
### 3.1 客户端连接
```
ws://example.com/ws?token=xxxx
```
- 客户端通过 Token 鉴权
- 服务器验证 Token 后,返回 AUTH_SUCCESS 或 AUTH_FAIL
### 3.2 服务端响应示例
**成功:**
```
{
"type": "AUTH",
"status": "success",
"userId": 1001,
"timestamp": 1700000000
}
```
**失败:**
```
{
"type": "AUTH",
"status": "fail",
"code": 1006,
"message": "Token无效或过期"
}
```
------
## 4. 心跳机制
### 4.1 客户端发送
```
{
"type": "HEARTBEAT",
"timestamp": 1700000000
}
```
### 4.2 服务器响应
```
{
"type": "HEARTBEAT",
"timestamp": 1700000000
}
```
- **客户端**:每隔 30 秒发送一次心跳
- **服务器**:若 2 倍心跳时间未收到消息,则断开连接
------
## 5. 消息传输
### 5.1 单聊消息
客户端发送:
```
{
"type": "MESSAGE",
"requestId": "uuid-001",
"from": 1001,
"to": 1002,
"chatType": "single",
"contentType": "text",
"content": "你好",
"timestamp": 1700000000
}
```
服务器推送给接收者:
```
{
"type": "MESSAGE",
"messageId": 50001,
"from": 1001,
"to": 1002,
"chatType": "single",
"contentType": "text",
"content": "你好",
"timestamp": 1700000000
}
```
------
### 5.2 群聊消息
```
{
"type": "MESSAGE",
"requestId": "uuid-002",
"from": 1001,
"to": 3001, // 群ID
"chatType": "group",
"contentType": "image",
"content": "http://img.example.com/xxx.jpg",
"timestamp": 1700000000
}
```
服务器会 **推送到群成员列表(除了自己)**
------
### 5.3 消息回执MESSAGE_ACK
客户端收到消息后发送:
```
{
"type": "MESSAGE_ACK",
"messageId": 50001,
"from": 1002,
"to": 1001,
"chatType": "single",
"status": "read",
"timestamp": 1700000000
}
```
服务器更新消息状态,并可推送给发送方。
------
### 5.4 消息撤回MESSAGE_RECALL
客户端请求撤回消息:
```
{
"type": "MESSAGE_RECALL",
"messageId": 50001,
"from": 1001,
"to": 1002,
"chatType": "single",
"timestamp": 1700000010
}
```
服务器验证是否允许撤回(时间限制、权限等),允许则推送给接收方:
```
{
"type": "MESSAGE_RECALL",
"messageId": 50001,
"from": 1001,
"chatType": "single",
"status": "success",
"timestamp": 1700000010
}
```
------
## 6. 好友 / 群邀请通知
### 6.1 好友申请FRIEND_REQUEST
```
{
"type": "FRIEND_REQUEST",
"requestId": "uuid-003",
"from": 1001,
"to": 1002,
"content": "加个好友吧",
"timestamp": 1700000020
}
```
### 6.2 群邀请GROUP_INVITE
```
{
"type": "GROUP_INVITE",
"inviteId": "uuid-004",
"groupId": 3001,
"inviter": 1001,
"invitee": 1003,
"content": "邀请你加入群聊",
"timestamp": 1700000030
}
```
------
## 7. 错误处理ERROR
```
{
"type": "ERROR",
"code": 2300,
"message": "消息发送失败",
"requestId": "uuid-001",
"timestamp": 1700000040
}
```
- **code** 对应响应 Code 规范
- **requestId** 可帮助客户端确认失败的具体请求
------
## 8. 断线重连
- 客户端断线后,尝试每隔 5 秒重连一次
- 重连成功后,重新发送 AUTH 消息进行鉴权
- 重连后可请求 **未读消息同步**message 表或 Redis 缓存)
------
## 9. 附录contentType 示例
| contentType | content 示例 | 描述 |
| ----------- | ---------------------------------- | ----------------- |
| text | "你好" | 文本消息 |
| image | "http://img.example.com/xxx.jpg" | 图片 URL |
| file | "http://file.example.com/xxx.pdf" | 文件 URL + 文件名 |
| voice | "http://audio.example.com/xxx.mp3" | 语音 URL + 时长 |
| system | "用户xxx加入群" | 系统消息 |

View File

@ -0,0 +1,144 @@
# 📘 接口响应 Code 设计文档
## 1. 响应数据结构
统一使用 JSON 格式:
```
{
"code": 0,
"message": "请求成功",
"data": {}
}
```
- **code**:数字型,业务状态码
- **message**:字符串,错误或提示信息
- **data**:对象/数组,返回的数据内容(可选)
------
## 2. Code 设计原则
1. **统一性**:所有接口返回结构一致。
2. **分级设计**分为系统级错误1xxx、业务错误2xxx+)。
3. **可扩展性**:预留范围,避免混乱。
------
## 3. Code 约定规范
### 3.1 成功类
| code | message | 说明 |
| ---- | ------- | ------------ |
| 0 | 成功 | 通用成功响应 |
------
### 3.2 系统级错误1000 ~ 1999
| code | message | 说明 |
| ---- | ---------- | ------------------ |
| 1000 | 系统错误 | 未知异常 |
| 1001 | 服务不可用 | 服务器维护中或宕机 |
| 1002 | 请求超时 | 后端超时 |
| 1003 | 参数错误 | 缺少或参数不合法 |
| 1004 | 数据库错误 | 数据库读写失败 |
| 1005 | 权限不足 | 无权限访问 |
| 1006 | 认证失败 | Token 无效/过期 |
------
### 3.3 用户相关错误2000 ~ 2099
| code | message | 说明 |
| ---- | ---------- | ---------------- |
| 2000 | 用户不存在 | 查询不到用户 |
| 2001 | 用户已存在 | 注册时用户已存在 |
| 2002 | 密码错误 | 登录密码错误 |
| 2003 | 用户被禁用 | 被管理员封禁 |
| 2004 | 登录过期 | 需重新登录 |
------
### 3.4 好友相关错误2100 ~ 2199
| code | message | 说明 |
| ---- | -------------- | ---------- |
| 2100 | 好友申请已存在 | 重复申请 |
| 2101 | 好友关系不存在 | 不是好友 |
| 2102 | 已经是好友 | 重复添加 |
| 2103 | 好友请求被拒绝 | 被对方拒绝 |
------
### 3.5 群聊相关错误2200 ~ 2299
| code | message | 说明 |
| ---- | ------------ | ------------- |
| 2200 | 群不存在 | 查询不到群 |
| 2201 | 已在群中 | 不能重复加入 |
| 2202 | 群成员已满 | 超出限制 |
| 2203 | 无加群权限 | 需要邀请/验证 |
| 2204 | 群邀请已过期 | 邀请链接过期 |
------
### 3.6 消息相关错误2300 ~ 2399
| code | message | 说明 |
| ---- | ---------------- | ------------------- |
| 2300 | 消息发送失败 | 发送时异常 |
| 2301 | 消息不存在 | 查询不到 |
| 2302 | 消息撤回失败 | 超过时间限制 |
| 2303 | 不支持的消息类型 | message_type 不合法 |
------
### 3.7 文件相关错误2400 ~ 2499
| code | message | 说明 |
| ---- | -------------- | ------------ |
| 2400 | 文件上传失败 | 存储服务错误 |
| 2401 | 文件不存在 | 下载时未找到 |
| 2402 | 文件大小超限 | 超过配置限制 |
| 2403 | 文件类型不支持 | 格式不允许 |
------
### 3.8 管理后台相关错误3000 ~ 3099
| code | message | 说明 |
| ---- | ------------ | ---------------- |
| 3000 | 管理员不存在 | 账号错误 |
| 3001 | 密码错误 | 后台登录失败 |
| 3002 | 角色不存在 | 角色未找到 |
| 3003 | 权限不足 | 无操作权限 |
| 3004 | 操作记录失败 | 后台日志写入失败 |
------
## 4. 响应示例
### 成功示例
```
{
"code": 0,
"message": "好友申请成功",
"data": {
"requestId": 12345
}
}
```
### 失败示例
```
{
"code": 2100,
"message": "好友申请已存在",
"data": null
}
```