核心交付:
- 新建 MeetingLifecycleService(6 钩子 + sync.Map 本地 timer + Redis key 双保险 + RescheduleFromRedis)
- 新建 MeetingCleanupTask(启动重建 timer + 每 N 秒扫 host_grace/empty_ttl 兜底 + 4h stale active 回收)
- MediaOrchestrator 新增 ResolveRouterID;HTTPMediaOrchestrator.CreateRouter 入口 sync.Map 幂等防御
- 业务层 JoinRoom 移除 CreateRouter 调用改走 CancelEmptyTTL + ResolveRouterID;LeaveRoom 空房分支改调 OnAllMembersLeft 不再立即销毁
- MeetingSignalService 新增 OnWSDisconnect 实现 ws.MeetingDisconnectHook;OnRoomJoin 追加 host 重连钩子
- ws.handler 定义 MeetingDisconnectHook 接口 + SetMeetingDisconnectHook,解耦 ws→meeting 反向依赖
- config 新增 MeetingConfig{HostGrace=120, EmptyRoomTTL=300, CleanupInterval=30, StaleRoomHours=4}
关键设计决策:
- Redis key TTL = 业务时长 + max(CleanupIntervalSeconds*2, 30s) buffer:避免本地 timer 与
Redis 自动过期同步到期导致 DEL 返回 0 被误判为"已被其他路径处理"而跳过业务逻辑
- Router 幂等双层防御(决策 q2_router_dedup=a2_both):业务层不重复调 + HTTP 层 sync.Map 命中直接返回
- 普通成员 WS 断开仅清 media 资源不动 participant 表(决策 q1_nonhost_disconnect=a1_keep_current)
E2E 验证:docs/verify/meeting_t8_verify.mjs PASS=20 FAIL=0,覆盖 5 场景:
- S1 host 宽限期过期自动转让(meeting.host.changed + DB host_id 更新)
- S2 宽限期内重连保留身份
- S3 empty_ttl 期内新成员加入复活房间
- S4 empty_ttl 过期 → 房间 Ended + 新 join 被拒
- S5 CreateRoom +1 Router / JoinRoom 不再创建新 Router(通过 media-server /internal/info stats.routers 断言)
media-server:/internal/info 响应追加 stats.routers + routers[] 供 E2E 断言 Router 幂等
文档同步:
- docs/progress/CURRENT_STATUS.md 头部 + 新增 Task 8 交付条目
- docs/plans/2026-04-21-phase2e-2-implementation.plan.md Task 8 标记完成 + 实际产出/决策/验证
- docs/api/frontend/meeting.md 补充 host.changed.auto_reason / room.ended.reason=system_error / 空房 TTL 复活语义 + Task 8 验证记录
- docs/architecture/system-architecture.md meeting 模块职责补充"会议生命周期状态机"
- .cursor/rules/project-context.mdc 追加 Task 8 条目并更新 Phase 2e-2 进度(Task 0-8 ✅)
Made-with: Cursor
EchoChat API 接口文档
本目录包含 EchoChat 系统所有接口定义,按端 + 功能模块两级目录组织,便于维护和查阅。 架构设计见
docs/architecture/system-architecture.md完整设计方案见docs/plans/2026-02-27-echochat-system-design.md
文档导航
前台用户端 (frontend/)
| 文档 | 模块 | 状态 | 说明 |
|---|---|---|---|
| frontend/auth.md | 用户认证 | ✅ Phase 1 | 注册、登录、Token 刷新、个人信息管理 |
| frontend/contact.md | 联系人 | ✅ Phase 2a | 17 个 API:好友申请/管理、好友分组、黑名单、搜索/推荐、在线状态 |
| frontend/websocket.md | WebSocket | ✅ Phase 2a | 前端 WebSocket 连接管理、事件协议、心跳、重连 |
| frontend/im.md | 即时通讯 | ✅ Phase 2b | 7 个 API:会话列表/置顶/删除/清空、历史消息、全局搜索、未读数 |
| frontend/group.md | 群聊管理 | ✅ Phase 2c | 16 个 API:建群/管理/成员/角色/禁言/公告/搜索/入群审批 |
| frontend/meeting.md | 会议 | ✅ Phase 2e-2 Task 5/6/7 | 12 个 REST 接口(创建/加入/离开/结束/详情/列表/邀请/踢人/转让主持人/发起聊天/拉聊天历史/邀请链接兑换)+ 13 个 WebSocket 信令事件(8 C→S + 5 核心 S→C 广播 + 会议内聊天/被踢定向推送),Redis 媒体资源追踪 + host 权限校验;Task 7 (2026-04-21) 已接入真实 mediasoup,返回值为 Node media-server 真实 Transport/Router/DTLS 参数 |
| frontend/notify.md | 通知中心 | ✅ Phase 2e-1 | 5 个 API:通知列表(游标分页)/未读数/标记已读/全部已读/管理员广播 + 2 个 WS 事件(notify.new/notify.unread.total) |
后台管理端 (admin/)
| 文档 | 模块 | 状态 | 说明 |
|---|---|---|---|
| admin/auth.md | 管理员认证 | ✅ Phase 1 | 管理员登录(验证 admin 角色) |
| admin/user.md | 用户管理 | ✅ Phase 1 | 用户列表/详情、状态管理、角色分配、创建用户 |
| admin/online.md | 在线监控 | ✅ Phase 2a | 在线用户列表、在线用户计数 |
| admin/contact.md | 好友关系管理 | ✅ Phase 2a | 好友关系列表(分页)、管理员解除好友关系 |
| admin/group.md | 群聊管理 | ✅ Phase 2c | 群列表/详情、管理员解散群聊 |
| admin/message.md | 消息管理 | ✅ Phase 2d | 消息列表/详情/撤回/删除、消息统计(5 个 API) |
| admin/meeting.md | 会议管理 | 📋 后续 | 会议列表/详情、强制结束、会议统计 |
| admin/system.md | 系统管理 | 📋 待定 | 仪表盘数据、操作日志、系统配置 |
跨端通用
| 文档 | 状态 | 说明 |
|---|---|---|
| websocket.md | ✅ Phase 2a/2b | WebSocket 实时事件协议(IM 消息收发/撤回/已读/输入、联系人通知、在线状态、心跳) |
通用规范
基础 URL
| 环境 | 地址 |
|---|---|
| 开发环境 | http://localhost:8085 |
| 生产环境 | https://api.echochat.com(待定) |
认证方式
除登录/注册等公开接口外,所有接口均需在请求头中携带 JWT Token:
Authorization: Bearer <access_token>
时间格式规范
系统所有时间字段统一使用 亚洲友好的日期时间字符串格式:
yyyy-MM-dd HH:mm:ss
示例:"2026-03-01 14:12:12"
- 所有 API 响应中的时间字段(
created_at、updated_at、last_login_at、started_at等)均使用此格式 - 所有 API 请求中的时间参数(如预约会议时间)也使用此格式
- WebSocket 消息中的时间字段同样遵循此格式
- 时区统一采用 Asia/Shanghai (UTC+8)
统一响应格式
成功响应:
{
"code": 0,
"message": "success",
"data": { ... },
"trace_id": "6478824e-2926-4d35-aa5f-047c8cfbb36b",
"time": "2026-02-27 18:00:00"
}
错误响应:
{
"code": 1001,
"message": "参数错误:邮箱格式不正确",
"trace_id": "66564073-c0b7-4cf6-a200-5df94e1d01f3",
"time": "2026-02-27 18:00:00"
}
trace_id 字段在所有响应中都返回,用于追踪同一请求在各层级日志中的关联。
错误码定义
通用错误码(1000-1099)
| 错误码 | 含义 | 说明 |
|---|---|---|
| 0 | 成功 | 请求处理成功 |
| 1001 | 参数错误 | 请求参数缺失或格式不正确 |
| 1002 | 未认证 | Token 缺失、过期或无效 |
| 1003 | 权限不足 | 当前用户角色无权执行此操作 |
| 1004 | 资源不存在 | 请求的目标资源不存在 |
| 1005 | 操作重复 | 如重复注册、重复添加好友等 |
认证模块错误码(2000-2099)
| 错误码 | 含义 | 说明 |
|---|---|---|
| 2001 | 用户名已存在 | 注册时用户名重复 |
| 2002 | 邮箱已注册 | 注册时邮箱重复 |
| 2003 | 账号或密码错误 | 登录失败 |
| 2004 | 账号已被禁用 | 用户状态为禁用 |
联系人模块错误码(2100-2199)
| 错误码 | 含义 | 说明 |
|---|---|---|
| 2101 | 不能添加自己 | 好友申请目标为自身 |
| 2102 | 已是好友关系 | 重复发送好友申请 |
| 2103 | 已被对方拉黑 | 被拉黑后无法发送申请 |
| 2104 | 申请不存在 | 待处理申请记录不存在或已处理 |
| 2105 | 好友关系不存在 | 尝试操作不存在的好友关系 |
| 2106 | 分组不存在 | 好友分组 ID 无效 |
IM 模块错误码(3000-3099)
| 错误码 | 含义 | 说明 |
|---|---|---|
| 3001 | 会话不存在 | IM 会话 ID 无效 |
| 3002 | 非会话成员 | 用户不在该会话中 |
| 3003 | 已被禁言 | 用户在该群聊中被禁言 |
会议模块错误码(4000-4099)
| 错误码 | 含义 | 说明 |
|---|---|---|
| 4001 | 会议不存在 | 会议号无效 |
| 4002 | 会议密码错误 | 加入会议时密码不匹配 |
| 4003 | 会议已满 | 参会人数已达上限 |
| 4004 | 会议已结束 | 尝试加入已结束的会议 |
系统错误码(5000-5099)
| 错误码 | 含义 | 说明 |
|---|---|---|
| 5001 | 系统内部错误 | 服务端未知错误 |
| 5002 | 服务暂不可用 | 依赖服务不可用(数据库、Redis 等) |
分页规范
支持分页的接口统一使用以下查询参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| page | int | 1 | 页码,从 1 开始 |
| page_size | int | 20 | 每页数量,最大 100 |
分页响应格式:
{
"code": 0,
"message": "ok",
"data": {
"list": [ ... ],
"total": 150,
"page": 1,
"page_size": 20
}
}
文档维护规则
- 新增接口时:在对应端+模块的文档中追加,保持格式一致
- 接口变更时:同步更新文档,必要时在接口描述中标注版本信息
- 新增模块时:在对应端目录下创建新文档,在本 README 导航表中添加链接
- 新增端时:创建新的端目录(如
open/开放 API),在导航中添加新分区 - 错误码新增时:在本文档的错误码定义中追加,保持各模块错误码区间不重叠
目录结构
docs/api/
├── README.md # 通用规范(本文件)
├── frontend/ # 前台用户端 API
│ ├── auth.md # 用户认证 ✅ Phase 1
│ ├── contact.md # 联系人管理(17 个 API) ✅ Phase 2a
│ ├── websocket.md # WebSocket 事件协议 ✅ Phase 2a
│ ├── im.md # 即时通讯(8 个 API) ✅ Phase 2b/2c
│ ├── group.md # 群聊管理(16 个 API) ✅ Phase 2c
│ ├── meeting.md # 会议(12 REST + 13 WS 事件) ✅ Phase 2e-2 (Task 5/6/7,真实 mediasoup)
│ └── notify.md # 通知(5 API + 2 WS 事件) ✅ Phase 2e-1
├── admin/ # 后台管理端 API
│ ├── auth.md # 管理员认证 ✅ Phase 1
│ ├── user.md # 用户管理 ✅ Phase 1
│ ├── online.md # 在线监控 ✅ Phase 2a
│ ├── contact.md # 好友关系管理 ✅ Phase 2a
│ ├── group.md # 群聊管理(3 个 API) ✅ Phase 2c
│ ├── message.md # 消息管理(5 个 API) ✅ Phase 2d
│ ├── meeting.md # 会议管理 📋 后续
│ └── system.md # 系统管理 📋 待定
└── websocket.md # WebSocket 全量事件协议 ✅ Phase 2a/2b/2c