29 KiB
直播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)
{
"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)
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)
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)
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)
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)
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)
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)
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, ...]
消息缓存(String,TTL=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. 服务端处理
- 生成msgId(UUID)
- 敏感词过滤
- 保存到MySQL
- 缓存到Redis(7天)
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优化
- 消息缓存设置TTL(7天)
- 使用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(用户认证)
- Jackson(JSON序列化)
- Hutool(工具类)
- Lombok(简化代码)
6.2 前端技术栈(Android)
网络库
- OkHttp(HTTP请求)
- OkHttp WebSocket(长连接)
UI框架
- Material Design Components
- RecyclerView(消息列表)
- ViewPager2(直播间)
工具库
- Gson(JSON解析)
- Glide(图片加载)
- EventBus(事件总线)
6.3 开发工具
- IntelliJ IDEA(后端开发)
- Android Studio(Android开发)
- Postman(API测试)
- Redis Desktop Manager(Redis管理)
- Navicat(数据库管理)
七、部署方案
7.1 服务器配置(初期)
单机部署方案
服务器:阿里云ECS
配置:4核8G 5M带宽
系统:CentOS 7.9
服务部署:
- Nginx(80/443端口)
- Spring Boot IM服务(8080端口)
- MySQL(3306端口)
- Redis(6379端口)
预估支持规模
- 同时在线:5000人
- 单直播间:500人
- 消息吞吐:5000条/秒
7.2 扩展方案(后期)
水平扩展
负载均衡(Nginx)
↓
IM服务集群(3台)
↓
Redis集群(主从)
↓
MySQL主从(读写分离)
支持规模
- 同时在线:5万人
- 单直播间:5000人
- 消息吞吐:5万条/秒
八、开发计划(7天)
Day 1-2:基础架构搭建
- 搭建Spring Boot项目
- 集成WebSocket
- 配置MySQL、Redis
- 实现用户认证(JWT)
- 实现连接管理模块
Day 3-4:核心功能开发
- 实现单聊消息收发
- 实现直播间弹幕
- 实现离线消息
- 实现消息存储
- 实现敏感词过滤
Day 5:业务功能开发
- 实现礼物打赏消息
- 实现系统通知
- 实现消息已读
- 实现历史消息查询
Day 6:Android客户端对接
- 实现WebSocket连接
- 实现消息收发UI
- 实现弹幕显示
- 实现礼物动画
Day 7:测试与优化
- 功能测试
- 压力测试(JMeter)
- 性能优化
- 部署上线
九、接口设计
9.1 WebSocket接口
连接地址
ws://domain/ws?token=xxx
客户端发送消息格式
{
"action": "sendMessage|sendBarrage|enterRoom|leaveRoom|heartbeat",
"data": {
// 具体数据
}
}
服务端推送消息格式
{
"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-SocketIO(Java WebSocket框架)
- t-io(国产高性能IM框架)
- OpenIM(开源IM解决方案)
C. 敏感词库
- 使用DFA算法实现高效过滤
- 词库来源:GitHub开源项目
文档版本: v1.0 编写日期: 2024-12-25 适用范围: 1-10万用户规模的直播IM系统