zhibo/直播IM系统技术方案.md

1516 lines
29 KiB
Markdown
Raw Normal View History

# 直播IM系统技术方案
## 一、项目概述
### 1.1 项目目标
搭建一个面向直播场景的即时通讯系统支持1-10万用户规模一周内完成MVP版本交付。
### 1.2 核心场景
**直播场景**
- 直播间实时弹幕
- 主播与观众互动消息
- 直播间礼物打赏
- 进入/离开直播间通知
**社交交友场景**
- 用户一对一私聊
- 好友申请与通知
- 私聊礼物赠送
- 语音消息发送
- 图片/视频分享
- 表情包发送
- 消息已读/未读状态
**互动场景**
- 作品评论通知
- 点赞通知
- 关注/粉丝通知
- @提醒通知
- 系统公告推送
### 1.3 技术选型原则
- 快速开发,优先使用成熟方案
- 架构简单,便于维护和扩展
- 成本可控,适合初期规模
---
## 二、系统架构设计
### 2.1 整体架构
```
客户端层Android App
API网关层Nginx
业务服务层
├── IM服务WebSocket/长连接)
├── REST API服务HTTP
└── 消息推送服务
数据存储层
├── MySQL用户数据、消息记录
├── Redis在线状态、消息缓存
└── MongoDB可选消息归档
```
### 2.2 核心模块
#### 2.2.1 连接管理模块
- WebSocket长连接维护
- 心跳检测30秒间隔
- 断线重连机制
- 在线状态管理
#### 2.2.2 消息路由模块
- 单聊消息路由
- 群聊(直播间)消息广播
- 消息优先级队列
- 消息去重
#### 2.2.3 消息存储模块
- 离线消息存储
- 历史消息查询
- 消息已读状态
- 消息漫游7天
#### 2.2.4 业务功能模块
- 弹幕发送与接收
- 礼物打赏消息(直播间+私聊)
- 好友关系管理
- 消息已读回执
- 语音消息处理
- 图片/视频消息
- 系统通知
- 敏感词过滤
- 消息撤回
---
## 三、技术实现方案
### 3.1 通信协议选择
#### 方案一WebSocket推荐
**优点:**
- 双向实时通信
- 浏览器原生支持
- 开发简单,调试方便
- 适合直播弹幕场景
**实现:**
```
协议ws:// 或 wss://生产环境必须用wss
框架Spring Boot + Spring WebSocket
心跳客户端30秒发送ping服务端响应pong
```
#### 方案二MQTT备选
**优点:**
- 轻量级协议
- 支持QoS消息质量保证
- 适合物联网和移动场景
**缺点:**
- 需要额外的Broker如Mosquitto、EMQ
- 学习成本稍高
**建议:** 一周交付选WebSocket后期可扩展MQTT
### 3.2 消息格式设计
#### 3.2.1 通用消息结构JSON
```json
{
"msgId": "uuid",
"msgType": "text|image|gift|system|barrage",
"fromUserId": "发送者ID",
"toUserId": "接收者ID私聊",
"roomId": "直播间ID弹幕",
"content": "消息内容",
"timestamp": 1640000000000,
"extra": {
"nickname": "用户昵称",
"avatar": "头像URL",
"giftId": "礼物ID打赏消息",
"giftCount": 1
}
}
```
#### 3.2.2 消息类型定义
| 类型 | 说明 | 场景 |
|------|------|------|
| text | 文本消息 | 私聊、弹幕 |
| image | 图片消息 | 私聊 |
| video | 视频消息 | 私聊 |
| voice | 语音消息 | 私聊 |
| emoji | 表情包消息 | 私聊 |
| gift | 礼物打赏 | 直播间、私聊 |
| barrage | 弹幕 | 直播间 |
| system | 系统通知 | 全局 |
| friend_request | 好友申请 | 社交 |
| friend_accept | 好友通过 | 社交 |
| like | 点赞通知 | 社交 |
| comment | 评论通知 | 社交 |
| follow | 关注通知 | 社交 |
| at_mention | @提醒 | 社交 |
| enter_room | 进入直播间 | 直播间 |
| leave_room | 离开直播间 | 直播间 |
| recall | 消息撤回 | 私聊 |
### 3.3 数据库设计
#### 3.3.1 MySQL表结构
**用户表user**
```sql
CREATE TABLE `user` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(50) UNIQUE NOT NULL,
`nickname` VARCHAR(50),
`avatar` VARCHAR(255),
`status` TINYINT DEFAULT 1 COMMENT '1-正常 0-禁用',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**会话表conversation**
```sql
CREATE TABLE `conversation` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`user_id` BIGINT NOT NULL,
`target_id` BIGINT NOT NULL COMMENT '对方用户ID或直播间ID',
`type` TINYINT NOT NULL COMMENT '1-单聊 2-直播间',
`last_msg_id` BIGINT,
`last_msg_time` DATETIME,
`unread_count` INT DEFAULT 0,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
UNIQUE KEY uk_user_target (user_id, target_id, type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**消息表message**
```sql
CREATE TABLE `message` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`msg_id` VARCHAR(64) UNIQUE NOT NULL,
`msg_type` VARCHAR(20) NOT NULL,
`from_user_id` BIGINT NOT NULL,
`to_user_id` BIGINT COMMENT '私聊接收者',
`room_id` BIGINT COMMENT '直播间ID',
`content` TEXT,
`extra` JSON COMMENT '扩展字段图片URL、语音时长、礼物信息等',
`status` TINYINT DEFAULT 1 COMMENT '1-正常 2-撤回 3-删除',
`is_read` TINYINT DEFAULT 0 COMMENT '0-未读 1-已读',
`read_at` DATETIME COMMENT '已读时间',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_from_user (from_user_id, created_at),
INDEX idx_to_user (to_user_id, created_at),
INDEX idx_room (room_id, created_at),
INDEX idx_msg_id (msg_id),
INDEX idx_unread (to_user_id, is_read)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**好友关系表friend**
```sql
CREATE TABLE `friend` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`user_id` BIGINT NOT NULL,
`friend_id` BIGINT NOT NULL,
`remark` VARCHAR(50) COMMENT '好友备注',
`status` TINYINT DEFAULT 1 COMMENT '1-正常 2-拉黑',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_user_friend (user_id, friend_id),
INDEX idx_user_id (user_id),
INDEX idx_friend_id (friend_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**好友申请表friend_request**
```sql
CREATE TABLE `friend_request` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`from_user_id` BIGINT NOT NULL,
`to_user_id` BIGINT NOT NULL,
`message` VARCHAR(200) COMMENT '申请留言',
`status` TINYINT DEFAULT 0 COMMENT '0-待处理 1-已同意 2-已拒绝',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_to_user (to_user_id, status),
INDEX idx_from_user (from_user_id),
UNIQUE KEY uk_from_to (from_user_id, to_user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**礼物记录表gift_record**
```sql
CREATE TABLE `gift_record` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`from_user_id` BIGINT NOT NULL COMMENT '送礼者',
`to_user_id` BIGINT NOT NULL COMMENT '收礼者',
`gift_id` INT NOT NULL,
`gift_name` VARCHAR(50),
`gift_price` INT NOT NULL COMMENT '礼物价格(金币)',
`count` INT DEFAULT 1 COMMENT '数量',
`total_price` INT NOT NULL COMMENT '总价',
`room_id` BIGINT COMMENT '直播间ID直播间送礼',
`scene` VARCHAR(20) NOT NULL COMMENT 'live-直播间 chat-私聊',
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_from_user (from_user_id, created_at),
INDEX idx_to_user (to_user_id, created_at),
INDEX idx_room (room_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
**直播间表live_room**
```sql
CREATE TABLE `live_room` (
`id` BIGINT PRIMARY KEY AUTO_INCREMENT,
`room_id` VARCHAR(50) UNIQUE NOT NULL,
`anchor_id` BIGINT NOT NULL COMMENT '主播ID',
`title` VARCHAR(100),
`cover` VARCHAR(255),
`status` TINYINT DEFAULT 1 COMMENT '1-直播中 0-已结束',
`online_count` INT DEFAULT 0,
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_anchor (anchor_id),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
```
#### 3.3.2 Redis数据结构
**在线用户Hash**
```
Key: online:users
Field: userId
Value: {serverId, connectTime, lastHeartbeat}
```
**直播间在线列表Set**
```
Key: room:online:{roomId}
Member: userId
```
**用户连接映射String**
```
Key: user:connection:{userId}
Value: {serverId, sessionId}
```
**离线消息队列List**
```
Key: offline:msg:{userId}
Value: [msgId1, msgId2, ...]
```
**消息缓存StringTTL=7天**
```
Key: msg:cache:{msgId}
Value: JSON消息体
```
---
## 四、核心功能实现
### 4.1 连接建立流程
```
1. 客户端发起WebSocket连接
ws://domain/ws?token=xxx
2. 服务端验证token
- 解析JWT token
- 验证用户身份
- 检查用户状态
3. 连接成功
- 保存连接到内存Map
- 更新Redis在线状态
- 返回连接成功消息
4. 拉取离线消息
- 从Redis获取离线消息ID列表
- 批量查询消息详情
- 推送给客户端
5. 启动心跳
- 客户端每30秒发送ping
- 服务端响应pong
- 超过90秒无心跳则断开连接
```
### 4.2 单聊消息流程
```
1. 客户端发送消息
{
"action": "sendMessage",
"toUserId": "123",
"msgType": "text",
"content": "你好"
}
2. 服务端处理
- 生成msgIdUUID
- 敏感词过滤
- 保存到MySQL
- 缓存到Redis7天
3. 消息路由
- 查询接收者在线状态
- 如果在线通过WebSocket推送
- 如果离线:存入离线消息队列
4. 客户端接收
- 收到消息后发送ACK确认
- 更新会话列表
- 显示消息内容
5. 已读回执(可选)
- 用户查看消息后发送已读状态
- 更新消息已读标记
- 通知发送方
```
### 4.3 直播间弹幕流程
```
1. 用户进入直播间
- 发送enterRoom消息
- 加入Redis直播间在线集合
- 广播进入消息(可选)
2. 发送弹幕
{
"action": "sendBarrage",
"roomId": "room_001",
"content": "主播666"
}
3. 服务端处理
- 频率限制1秒1条
- 敏感词过滤
- 保存到MySQL可异步
- 不缓存到Redis弹幕量大
4. 消息广播
- 获取直播间所有在线用户
- 遍历推送消息
- 失败的用户从在线列表移除
5. 离开直播间
- 发送leaveRoom消息
- 从Redis在线集合移除
```
### 4.4 礼物打赏流程
**场景一:直播间送礼**
```
1. 客户端发送礼物
{
"action": "sendGift",
"roomId": "room_001",
"anchorId": "456",
"giftId": "gift_001",
"count": 1
}
2. 服务端处理
- 验证用户余额
- 扣除金币
- 增加主播收益
- 保存打赏记录
3. 消息广播
- 构造礼物消息
- 广播到直播间所有用户
- 触发礼物动画
4. 通知主播
- 发送私信通知
- 更新收益统计
```
**场景二:私聊送礼(社交场景)**
```
1. 客户端发送礼物
{
"action": "sendPrivateGift",
"toUserId": "789",
"giftId": "gift_002",
"count": 1,
"message": "送你一朵玫瑰"
}
2. 服务端处理
- 验证用户余额
- 扣除金币
- 增加对方收益
- 保存礼物记录
- 构造礼物消息
3. 消息推送
- 推送给接收者
- 显示礼物卡片
- 触发礼物动画
- 更新会话列表
4. 收益通知
- 发送收益通知
- 更新用户余额
```
### 4.5 好友关系管理
**添加好友流程**
```
1. 发送好友申请
{
"action": "sendFriendRequest",
"toUserId": "123",
"message": "你好,可以加个好友吗?"
}
2. 服务端处理
- 检查是否已是好友
- 检查是否已发送过申请
- 保存好友申请记录
- 构造申请通知消息
3. 推送通知
- 推送给目标用户
- 显示好友申请红点
- 更新申请列表
4. 处理申请
{
"action": "handleFriendRequest",
"requestId": "456",
"accept": true
}
5. 同意后处理
- 更新申请状态
- 双向添加好友关系
- 发送同意通知
- 创建会话
```
**删除好友流程**
```
1. 客户端请求删除
{
"action": "deleteFriend",
"friendId": "123"
}
2. 服务端处理
- 删除好友关系
- 保留历史消息(可选)
- 发送删除通知(可选)
```
### 4.6 多媒体消息处理
**图片消息流程**
```
1. 上传图片
POST /api/upload/image
- 客户端先上传图片到服务器
- 返回图片URL和缩略图URL
2. 发送图片消息
{
"action": "sendMessage",
"toUserId": "123",
"msgType": "image",
"content": "imageUrl",
"extra": {
"thumbnail": "thumbnailUrl",
"width": 1080,
"height": 1920,
"size": 102400
}
}
3. 服务端处理
- 验证图片URL合法性
- 保存消息记录
- 推送给接收者
4. 客户端显示
- 先显示缩略图
- 点击查看大图
- 支持图片保存
```
**语音消息流程**
```
1. 录制语音
- 客户端录制语音最长60秒
- 转换为MP3/AAC格式
- 上传到服务器
2. 发送语音消息
{
"action": "sendMessage",
"toUserId": "123",
"msgType": "voice",
"content": "voiceUrl",
"extra": {
"duration": 15,
"size": 51200
}
}
3. 服务端处理
- 验证语音文件
- 保存消息记录
- 推送给接收者
4. 客户端播放
- 显示语音时长
- 点击播放
- 显示播放进度
- 标记已读
```
**视频消息流程**
```
1. 上传视频
POST /api/upload/video
- 限制视频大小如50MB
- 限制视频时长如30秒
- 生成视频封面
2. 发送视频消息
{
"action": "sendMessage",
"toUserId": "123",
"msgType": "video",
"content": "videoUrl",
"extra": {
"cover": "coverUrl",
"duration": 20,
"width": 720,
"height": 1280,
"size": 5242880
}
}
3. 客户端显示
- 显示视频封面
- 显示时长标识
- 点击播放
```
### 4.7 消息已读回执
**已读状态更新**
```
1. 用户查看消息
{
"action": "markAsRead",
"conversationId": "123",
"lastMsgId": "msg_456"
}
2. 服务端处理
- 更新消息已读状态
- 更新会话未读数
- 记录已读时间
3. 推送已读回执
- 通知发送方消息已读
- 显示"已读"标识
- 更新发送方会话列表
```
**未读消息统计**
```
1. 获取未读数
GET /api/message/unreadCount
Response: {
"totalUnread": 15,
"conversations": [
{"conversationId": 1, "unread": 5},
{"conversationId": 2, "unread": 10}
]
}
2. 实时更新
- 收到新消息时更新未读数
- 标记已读时减少未读数
- 推送未读数变化
```
### 4.8 消息撤回功能
**撤回流程**
```
1. 客户端请求撤回
{
"action": "recallMessage",
"msgId": "msg_123"
}
2. 服务端验证
- 检查消息是否存在
- 检查是否是发送者本人
- 检查是否在2分钟内
- 更新消息状态为已撤回
3. 推送撤回通知
- 通知接收者消息已撤回
- 显示"对方撤回了一条消息"
- 更新会话最后一条消息
4. 客户端处理
- 移除或替换消息内容
- 显示撤回提示
```
### 4.9 社交互动通知
**点赞通知**
```
1. 用户点赞作品/评论
POST /api/like
{
"targetType": "work|comment",
"targetId": 123
}
2. 服务端处理
- 保存点赞记录
- 构造通知消息
- 推送给作品作者
3. 通知消息格式
{
"type": "like",
"data": {
"userId": 456,
"username": "张三",
"avatar": "xxx",
"targetType": "work",
"targetId": 123,
"targetTitle": "作品标题",
"timestamp": 1640000000000
}
}
```
**评论通知**
```
1. 用户发表评论
POST /api/comment
{
"workId": 123,
"content": "很棒的作品!"
}
2. 服务端处理
- 保存评论记录
- 构造通知消息
- 推送给作品作者
3. @提醒处理
- 解析评论中的@用户
- 发送@提醒通知
- 推送给被@的用户
```
**关注通知**
```
1. 用户关注他人
POST /api/follow
{
"targetUserId": 123
}
2. 服务端处理
- 保存关注关系
- 构造通知消息
- 推送给被关注者
3. 通知消息
{
"type": "follow",
"data": {
"userId": 456,
"username": "张三",
"avatar": "xxx",
"timestamp": 1640000000000
}
}
```
### 4.5 系统通知流程
```
1. 后台触发通知
- 关注通知
- 点赞通知
- 评论通知
- 系统公告
- 审核通知
2. 服务端处理
- 构造系统消息
- 保存到MySQL
- 推送给目标用户
3. 客户端接收
- 显示通知红点
- 弹出提示(可选)
- 更新通知列表
```
---
## 五、性能优化方案
### 5.1 连接优化
**单机连接数优化**
- 使用Netty或Spring WebFlux异步非阻塞
- 单机支持10万+连接
- 调整系统参数ulimit -n 100000
**连接保活**
- 客户端心跳30秒
- 服务端超时90秒
- 减少无效连接占用
### 5.2 消息优化
**弹幕限流**
- 用户级别1秒1条
- 直播间级别每秒1000条超过则丢弃
- 使用Redis令牌桶算法
**消息批量处理**
- 弹幕批量入库100条/批次)
- 离线消息批量拉取50条/次)
- 减少数据库IO
**消息压缩**
- 启用WebSocket压缩permessage-deflate
- 减少30-50%流量
### 5.3 存储优化
**MySQL优化**
- 消息表按月分表
- 历史消息归档到MongoDB
- 只保留3个月热数据
**Redis优化**
- 消息缓存设置TTL7天
- 使用Redis Cluster后期扩展
- 离线消息队列限制长度最多100条
### 5.4 广播优化
**直播间消息广播**
- 异步推送,不阻塞主线程
- 失败重试1次超时则放弃
- 单次广播超时时间100ms
**分组广播(后期优化)**
- 将直播间用户分组每组1000人
- 多线程并行推送
- 提升广播效率
---
## 六、技术栈选型
### 6.1 后端技术栈
**核心框架**
- Spring Boot 2.7+
- Spring WebSocket
- Spring Data JPA / MyBatis-Plus
**中间件**
- MySQL 8.0(主数据库)
- Redis 6.0+(缓存、在线状态)
- Nginx反向代理、负载均衡
**工具库**
- JWT用户认证
- JacksonJSON序列化
- Hutool工具类
- Lombok简化代码
### 6.2 前端技术栈Android
**网络库**
- OkHttpHTTP请求
- OkHttp WebSocket长连接
**UI框架**
- Material Design Components
- RecyclerView消息列表
- ViewPager2直播间
**工具库**
- GsonJSON解析
- Glide图片加载
- EventBus事件总线
### 6.3 开发工具
- IntelliJ IDEA后端开发
- Android StudioAndroid开发
- PostmanAPI测试
- Redis Desktop ManagerRedis管理
- Navicat数据库管理
---
## 七、部署方案
### 7.1 服务器配置(初期)
**单机部署方案**
```
服务器阿里云ECS
配置4核8G 5M带宽
系统CentOS 7.9
服务部署:
- Nginx80/443端口
- Spring Boot IM服务8080端口
- MySQL3306端口
- Redis6379端口
```
**预估支持规模**
- 同时在线5000人
- 单直播间500人
- 消息吞吐5000条/秒
### 7.2 扩展方案(后期)
**水平扩展**
```
负载均衡Nginx
IM服务集群3台
Redis集群主从
MySQL主从读写分离
```
**支持规模**
- 同时在线5万人
- 单直播间5000人
- 消息吞吐5万条/秒
---
## 八、开发计划7天
### Day 1-2基础架构搭建
- [x] 搭建Spring Boot项目
- [x] 集成WebSocket
- [x] 配置MySQL、Redis
- [x] 实现用户认证JWT
- [x] 实现连接管理模块
### Day 3-4核心功能开发
- [x] 实现单聊消息收发
- [x] 实现直播间弹幕
- [x] 实现离线消息
- [x] 实现消息存储
- [x] 实现敏感词过滤
### Day 5业务功能开发
- [x] 实现礼物打赏消息
- [x] 实现系统通知
- [x] 实现消息已读
- [x] 实现历史消息查询
### Day 6Android客户端对接
- [x] 实现WebSocket连接
- [x] 实现消息收发UI
- [x] 实现弹幕显示
- [x] 实现礼物动画
### Day 7测试与优化
- [x] 功能测试
- [x] 压力测试JMeter
- [x] 性能优化
- [x] 部署上线
---
## 九、接口设计
### 9.1 WebSocket接口
**连接地址**
```
ws://domain/ws?token=xxx
```
**客户端发送消息格式**
```json
{
"action": "sendMessage|sendBarrage|enterRoom|leaveRoom|heartbeat",
"data": {
// 具体数据
}
}
```
**服务端推送消息格式**
```json
{
"type": "message|barrage|gift|system|notification",
"data": {
// 具体数据
}
}
```
### 9.2 HTTP接口
**用户认证**
```
POST /api/auth/login
Body: {
"username": "user123",
"password": "xxx"
}
Response: {
"code": 200,
"data": {
"token": "jwt_token",
"userId": 123,
"username": "user123",
"nickname": "张三",
"avatar": "xxx"
}
}
```
**好友相关接口**
**获取好友列表**
```
GET /api/friend/list
Response: {
"code": 200,
"data": [
{
"friendId": 123,
"username": "user123",
"nickname": "张三",
"avatar": "xxx",
"remark": "备注名",
"online": true,
"lastOnlineTime": "2024-12-25 10:00:00"
}
]
}
```
**发送好友申请**
```
POST /api/friend/request
Body: {
"toUserId": 123,
"message": "你好,可以加个好友吗?"
}
Response: {
"code": 200,
"message": "申请已发送"
}
```
**获取好友申请列表**
```
GET /api/friend/requests?status=0
Response: {
"code": 200,
"data": [
{
"requestId": 1,
"fromUserId": 456,
"username": "user456",
"nickname": "李四",
"avatar": "xxx",
"message": "你好",
"status": 0,
"createdAt": "2024-12-25 10:00:00"
}
]
}
```
**处理好友申请**
```
POST /api/friend/handle
Body: {
"requestId": 1,
"accept": true
}
Response: {
"code": 200,
"message": "已同意好友申请"
}
```
**删除好友**
```
DELETE /api/friend/{friendId}
Response: {
"code": 200,
"message": "已删除好友"
}
```
**会话相关接口**
**获取会话列表**
```
GET /api/conversation/list
Response: {
"code": 200,
"data": [
{
"conversationId": 1,
"type": 1,
"targetId": 123,
"targetName": "张三",
"targetAvatar": "xxx",
"lastMessage": "你好",
"lastMessageType": "text",
"lastTime": "2024-12-25 10:00:00",
"unreadCount": 3,
"online": true
}
]
}
```
**删除会话**
```
DELETE /api/conversation/{conversationId}
Response: {
"code": 200,
"message": "会话已删除"
}
```
**消息相关接口**
**获取历史消息**
```
GET /api/message/history?targetId=123&pageSize=20&lastMsgId=xxx
Response: {
"code": 200,
"data": {
"messages": [
{
"msgId": "msg_001",
"msgType": "text",
"fromUserId": 456,
"toUserId": 123,
"content": "你好",
"extra": {},
"status": 1,
"isRead": 1,
"createdAt": "2024-12-25 10:00:00"
}
],
"hasMore": true
}
}
```
**上传图片**
```
POST /api/upload/image
Content-Type: multipart/form-data
Body: file=xxx
Response: {
"code": 200,
"data": {
"url": "https://xxx.com/image.jpg",
"thumbnail": "https://xxx.com/image_thumb.jpg",
"width": 1080,
"height": 1920,
"size": 102400
}
}
```
**上传语音**
```
POST /api/upload/voice
Content-Type: multipart/form-data
Body: file=xxx
Response: {
"code": 200,
"data": {
"url": "https://xxx.com/voice.mp3",
"duration": 15,
"size": 51200
}
}
```
**上传视频**
```
POST /api/upload/video
Content-Type: multipart/form-data
Body: file=xxx
Response: {
"code": 200,
"data": {
"url": "https://xxx.com/video.mp4",
"cover": "https://xxx.com/cover.jpg",
"duration": 20,
"width": 720,
"height": 1280,
"size": 5242880
}
}
```
**发送图片消息**
```
POST /api/message/sendImage
Body: {
"toUserId": 123,
"imageUrl": "xxx",
"thumbnail": "xxx",
"width": 1080,
"height": 1920
}
Response: {
"code": 200,
"data": {
"msgId": "msg_001"
}
}
```
**标记消息已读**
```
POST /api/message/markRead
Body: {
"conversationId": 1,
"lastMsgId": "msg_456"
}
Response: {
"code": 200,
"message": "已标记为已读"
}
```
**撤回消息**
```
POST /api/message/recall
Body: {
"msgId": "msg_123"
}
Response: {
"code": 200,
"message": "消息已撤回"
}
```
**获取未读消息数**
```
GET /api/message/unreadCount
Response: {
"code": 200,
"data": {
"totalUnread": 15,
"conversations": [
{"conversationId": 1, "unread": 5},
{"conversationId": 2, "unread": 10}
]
}
}
```
**礼物相关接口**
**获取礼物列表**
```
GET /api/gift/list
Response: {
"code": 200,
"data": [
{
"giftId": 1,
"name": "玫瑰",
"icon": "xxx",
"price": 10,
"animation": "rose_animation"
}
]
}
```
**私聊送礼**
```
POST /api/gift/sendPrivate
Body: {
"toUserId": 123,
"giftId": 1,
"count": 1,
"message": "送你一朵玫瑰"
}
Response: {
"code": 200,
"data": {
"recordId": 1,
"balance": 990
}
}
```
**直播间送礼**
```
POST /api/gift/sendLive
Body: {
"roomId": "room_001",
"anchorId": 456,
"giftId": 1,
"count": 1
}
Response: {
"code": 200,
"data": {
"recordId": 1,
"balance": 990
}
}
```
**获取礼物记录**
```
GET /api/gift/records?type=send&pageSize=20&page=1
Response: {
"code": 200,
"data": {
"records": [
{
"recordId": 1,
"fromUserId": 123,
"toUserId": 456,
"giftName": "玫瑰",
"count": 1,
"totalPrice": 10,
"scene": "chat",
"createdAt": "2024-12-25 10:00:00"
}
],
"total": 100
}
}
```
**通知相关接口**
**获取通知列表**
```
GET /api/notification/list?type=all&pageSize=20&page=1
Response: {
"code": 200,
"data": [
{
"notificationId": 1,
"type": "like",
"fromUserId": 456,
"fromUsername": "张三",
"fromAvatar": "xxx",
"content": "赞了你的作品",
"targetType": "work",
"targetId": 123,
"isRead": 0,
"createdAt": "2024-12-25 10:00:00"
}
]
}
```
**标记通知已读**
```
POST /api/notification/markRead
Body: {
"notificationIds": [1, 2, 3]
}
Response: {
"code": 200,
"message": "已标记为已读"
}
```
**获取未读通知数**
```
GET /api/notification/unreadCount
Response: {
"code": 200,
"data": {
"like": 5,
"comment": 3,
"follow": 2,
"system": 1,
"total": 11
}
}
```
---
## 十、安全方案
### 10.1 认证鉴权
- 使用JWT token认证
- Token有效期7天
- 刷新Token机制
### 10.2 消息安全
- 敏感词过滤(本地词库)
- 消息内容长度限制500字符
- 图片内容审核(接入第三方)
### 10.3 防刷机制
- 消息发送频率限制
- IP黑名单
- 用户封禁机制
### 10.4 数据安全
- WebSocket使用wss加密
- 数据库密码加密存储
- 敏感信息脱敏
---
## 十一、监控与运维
### 11.1 监控指标
- 在线用户数
- 消息发送量QPS
- 接口响应时间
- 服务器CPU/内存/网络
### 11.2 日志管理
- 使用SLF4J + Logback
- 日志分级ERROR、WARN、INFO
- 日志文件按天切割
- 保留30天日志
### 11.3 告警机制
- 服务宕机告警
- 接口异常告警
- 资源使用告警
---
## 十二、成本预估
### 12.1 服务器成本
- 阿里云ECS 4核8G约300元/月
- 带宽5M约50元/月
- 总计约350元/月
### 12.2 开发成本
- 后端开发3人天
- Android开发2人天
- 测试1人天
- 总计6人天
### 12.3 第三方服务(可选)
- 图片审核:按量计费
- 短信通知:按量计费
- CDN加速按流量计费
---
## 十三、风险与应对
### 13.1 技术风险
**风险:** 单机性能瓶颈
**应对:** 提前设计水平扩展方案,预留扩展接口
**风险:** 消息丢失
**应对:** 实现消息ACK机制离线消息队列
**风险:** 直播间消息风暴
**应对:** 消息限流、降级策略
### 13.2 业务风险
**风险:** 用户量超预期
**应对:** 快速扩容方案,提前准备服务器
**风险:** 恶意刷屏
**应对:** 频率限制、封禁机制
---
## 十四、后续优化方向
### 14.1 功能优化
- 消息撤回
- 消息转发
- @提醒功能
- 表情包支持
- 语音/视频通话
### 14.2 性能优化
- 引入消息队列RabbitMQ/Kafka
- 数据库分库分表
- 引入ElasticSearch消息搜索
- CDN加速图片、语音
### 14.3 架构优化
- 微服务拆分
- 服务注册与发现Nacos
- 分布式链路追踪SkyWalking
- 容器化部署Docker + K8s
---
## 附录
### A. 参考资料
- WebSocket协议RFC 6455
- MQTT协议MQTT 3.1.1
- 即时通讯技术选型https://www.zhihu.com/question/xxx
### B. 开源方案参考
- Netty-SocketIOJava WebSocket框架
- t-io国产高性能IM框架
- OpenIM开源IM解决方案
### C. 敏感词库
- 使用DFA算法实现高效过滤
- 词库来源GitHub开源项目
---
**文档版本:** v1.0
**编写日期:** 2024-12-25
**适用范围:** 1-10万用户规模的直播IM系统