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

1516 lines
29 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 直播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系统