283 lines
8.5 KiB
Markdown
283 lines
8.5 KiB
Markdown
# 进房接口 Flutter 对接
|
||
|
||
## 接口地址
|
||
|
||
```http
|
||
POST /api/v1/rooms/join
|
||
Authorization: Bearer <access_token>
|
||
Content-Type: application/json
|
||
```
|
||
|
||
新版本进房默认使用 `response_mode=lite`。`full` 仍保留给旧客户端兼容,不建议新 Flutter 首屏使用。
|
||
|
||
## 参数
|
||
|
||
Body:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `room_id` | string | 是 | 房间 ID。 |
|
||
| `command_id` | string | 是 | 本次进房命令 ID。同一次点击超时重试复用同一个值,下一次重新进房换新值。 |
|
||
| `role` | string | 否 | 不传默认 `audience`。房主身份由服务端按房间 owner 判断,客户端不要靠传 `owner` 获取权限。 |
|
||
| `password` | string | 否 | 密码房传房间密码,非密码房不传或传空。 |
|
||
| `response_mode` | string | 是 | 新版固定传 `lite`。可选值:`lite` / `full`。 |
|
||
|
||
请求示例:
|
||
|
||
```json
|
||
{
|
||
"room_id": "lalu_abc123",
|
||
"command_id": "cmd_join_room_lalu_abc123_10001_1778000001000",
|
||
"role": "audience",
|
||
"password": "",
|
||
"response_mode": "lite"
|
||
}
|
||
```
|
||
|
||
也支持 query 参数:
|
||
|
||
```http
|
||
POST /api/v1/rooms/join?response_mode=lite
|
||
```
|
||
|
||
Flutter 建议放在 body 里,避免调用层漏拼 query。
|
||
|
||
## 返回值
|
||
|
||
统一外壳:
|
||
|
||
```json
|
||
{
|
||
"code": "OK",
|
||
"message": "ok",
|
||
"request_id": "req_xxx",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
成功返回示例:
|
||
|
||
```json
|
||
{
|
||
"code": "OK",
|
||
"message": "ok",
|
||
"request_id": "req_xxx",
|
||
"data": {
|
||
"result": {
|
||
"applied": true,
|
||
"room_version": 8,
|
||
"server_time_ms": 1778000001123
|
||
},
|
||
"room": {
|
||
"room_id": "lalu_abc123",
|
||
"im_group_id": "lalu_abc123",
|
||
"room_short_id": "10001",
|
||
"title": "Live Room",
|
||
"cover_url": "https://cdn.example/room.png",
|
||
"background_url": "https://cdn.example/bg.png",
|
||
"description": "welcome",
|
||
"owner_user_id": "10001",
|
||
"mode": "voice",
|
||
"status": "active",
|
||
"chat_enabled": true,
|
||
"locked": false,
|
||
"heat": 88,
|
||
"online_count": 200,
|
||
"seat_count": 10,
|
||
"occupied_seat_count": 2,
|
||
"visible_region_id": 1001,
|
||
"version": 8
|
||
},
|
||
"viewer": {
|
||
"user_id": "10001",
|
||
"role": "audience",
|
||
"joined_at_ms": 1778000001000,
|
||
"last_seen_at_ms": 1778000001100
|
||
},
|
||
"seats": [
|
||
{
|
||
"seat_no": 1,
|
||
"user_id": "10002",
|
||
"locked": false,
|
||
"publish_state": "publishing",
|
||
"mic_session_id": "mic_10002",
|
||
"publish_deadline_ms": 1778000030000,
|
||
"mic_muted": false,
|
||
"seat_status": "publishing",
|
||
"mic_heartbeat_at_ms": 1778000000000,
|
||
"gift_value": 0
|
||
},
|
||
{
|
||
"seat_no": 2,
|
||
"locked": false,
|
||
"mic_muted": false,
|
||
"gift_value": 0
|
||
}
|
||
],
|
||
"profiles": [
|
||
{
|
||
"user_id": "10001",
|
||
"username": "host",
|
||
"avatar": "https://cdn.example/avatar.png",
|
||
"display_user_id": "10001"
|
||
},
|
||
{
|
||
"user_id": "10002",
|
||
"username": "speaker",
|
||
"avatar": "https://cdn.example/avatar2.png",
|
||
"display_user_id": "10002"
|
||
}
|
||
],
|
||
"im": {
|
||
"group_id": "lalu_abc123",
|
||
"need_join_group": true
|
||
},
|
||
"rtc": {
|
||
"need_token": true,
|
||
"available": true,
|
||
"token": {
|
||
"sdk_app_id": 1400000000,
|
||
"user_id": "10001",
|
||
"rtc_user_id": "10001",
|
||
"user_sig": "xxx",
|
||
"expire_at_ms": 1778007200000,
|
||
"room_id": "lalu_abc123",
|
||
"rtc_room_id": "lalu_abc123",
|
||
"rtc_room_id_type": "string",
|
||
"str_room_id": "lalu_abc123",
|
||
"app_scene": "voice_chat_room",
|
||
"role": "user"
|
||
}
|
||
},
|
||
"server_time_ms": 1778000001123
|
||
}
|
||
}
|
||
```
|
||
|
||
字段说明:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| `data.result.applied` | 本次进房是否真正写入。重复 `command_id` 重试可能为 `false`。 |
|
||
| `data.result.room_version` | 房间版本,用于客户端状态更新判断。 |
|
||
| `data.room.room_id` | 房间 ID。 |
|
||
| `data.room.im_group_id` | 腾讯 IM 房间群 ID。当前通常等于 `room_id`,客户端仍以返回值为准。 |
|
||
| `data.room.online_count` | 房间在线人数。`lite` 不返回在线用户明细,只返回人数。 |
|
||
| `data.room.seat_count` | 麦位总数。 |
|
||
| `data.room.occupied_seat_count` | 已占用麦位数。 |
|
||
| `data.viewer` | 当前登录用户在房间内的 presence。 |
|
||
| `data.viewer.role` | 当前用户房间角色,房主会由服务端返回 `owner`。 |
|
||
| `data.seats` | 首屏麦位状态。 |
|
||
| `data.seats[].user_id` | 麦上用户 ID;空麦不返回该字段。 |
|
||
| `data.seats[].publish_state` | 麦上发流状态,常见值:`pending_publish` / `publishing`。 |
|
||
| `data.seats[].mic_session_id` | 麦位发流会话 ID。麦上心跳、发流确认需要使用它。 |
|
||
| `data.seats[].seat_status` | 麦位展示状态,常见值:`empty` / `locked` / `occupied` / `publishing` / `muted`。 |
|
||
| `data.profiles` | 首屏基础资料,只包含房主、当前用户、麦上用户。 |
|
||
| `data.profiles[].username` | 昵称。 |
|
||
| `data.profiles[].avatar` | 头像。 |
|
||
| `data.profiles[].display_user_id` | 展示 ID。 |
|
||
| `data.im.group_id` | Flutter 调腾讯 IM `joinGroup` 使用的群 ID。 |
|
||
| `data.im.need_join_group` | 为 `true` 时需要加入腾讯 IM 群。 |
|
||
| `data.rtc.available` | 是否拿到 RTC 票据。 |
|
||
| `data.rtc.token` | RTC 进房票据。`available=false` 时可能为空。 |
|
||
| `data.rtc.reason` | RTC 不可用原因。业务进房成功时,RTC 不可用不代表进房失败。 |
|
||
| `data.server_time_ms` | 服务端时间,UTC epoch milliseconds。 |
|
||
|
||
`lite` 不返回这些内容:
|
||
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| `contribution_rank` | 贡献榜不在进房首屏主包返回。 |
|
||
| `profiles[].avatar_frame` | 头像框后置拉。 |
|
||
| `profiles[].profile_card` | 资料卡后置拉。 |
|
||
| `profiles[].vehicle` | 座驾后置拉。 |
|
||
| `profiles[].mic_seat_animation` | 麦位动画后置拉。 |
|
||
| `profiles[].badges` | 等级/成就徽章后置拉。 |
|
||
| `profiles[].vip` | VIP 展示后置拉。 |
|
||
|
||
## 相关 IM
|
||
|
||
进房成功后 Flutter 执行:
|
||
|
||
```text
|
||
1. POST /api/v1/rooms/join,body 传 response_mode=lite
|
||
2. 如果 data.im.need_join_group=true,调用腾讯 IM joinGroup(data.im.group_id)
|
||
3. joinGroup 成功或已在群内,都按进房 IM 成功处理
|
||
4. 页面开始房间 heartbeat
|
||
5. 如果 data.rtc.available=true,用 data.rtc.token 进入 RTC
|
||
```
|
||
|
||
说明:
|
||
|
||
| 项 | 说明 |
|
||
| --- | --- |
|
||
| IM 登录 | 进房接口不返回 IM UserSig。Flutter 仍然通过 `GET /api/v1/im/usersig` 获取并登录腾讯 IM。 |
|
||
| IM 入群 | 必须先 `JoinRoom` 成功,再调腾讯 IM `joinGroup`。不要先入 IM 群。 |
|
||
| 入房广播 | 服务端会发 `RoomUserJoined` 房间事件。Flutter 按现有房间 IM 事件逻辑展示入房飘窗。 |
|
||
| 重复进房 | 用户重新打开房间页或重连时,服务端仍会给展示用入房事件,Flutter 正常展示即可。 |
|
||
| 入场座驾 | `lite` 进房不携带座驾快照。座驾、头像框、资料卡、麦位动画等展示资料在进房 UI 出来后异步补齐。 |
|
||
|
||
## 后置资料接口
|
||
|
||
进房首屏出来后,再按需要异步拉展示资料:
|
||
|
||
```http
|
||
GET /api/v1/users/room-display-profiles:batch?user_ids=10001,10002
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
参数:
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `user_ids` | string | 是 | 逗号分隔的用户 ID。也支持多个 `user_id=10001&user_id=10002`。 |
|
||
|
||
返回值:
|
||
|
||
```json
|
||
{
|
||
"code": "OK",
|
||
"message": "ok",
|
||
"request_id": "req_xxx",
|
||
"data": {
|
||
"profiles": [
|
||
{
|
||
"user_id": "10001",
|
||
"username": "host",
|
||
"avatar": "https://cdn.example/avatar.png",
|
||
"display_user_id": "10001",
|
||
"avatar_frame": {},
|
||
"profile_card": {},
|
||
"vehicle": {},
|
||
"mic_seat_animation": {},
|
||
"badges": [],
|
||
"vip": {},
|
||
"level": {},
|
||
"level_badges": {},
|
||
"charm": 0
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
当前用户自己的装扮也可以后置拉:
|
||
|
||
```http
|
||
GET /api/v1/appearance
|
||
GET /api/v1/users/me/appearance
|
||
```
|
||
|
||
## 常见错误
|
||
|
||
| code | HTTP | 说明 |
|
||
| --- | --- | --- |
|
||
| `INVALID_JSON` | 400 | 请求体不是合法 JSON。 |
|
||
| `INVALID_ARGUMENT` | 400 | 参数错误,例如 `response_mode` 不是 `lite` 或 `full`。 |
|
||
| `UNAUTHORIZED` | 401 | 未登录或 token 无效。 |
|
||
| `PROFILE_REQUIRED` | 403 | 用户资料未补全。 |
|
||
| `PERMISSION_DENIED` | 403 | 密码错误、被踢/被禁等权限问题。 |
|
||
| `ROOM_CLOSED` | 409 | 房间已关闭;非房主不能进入。 |
|
||
| `NOT_FOUND` | 404 | 房间不存在。 |
|
||
| `UPSTREAM_ERROR` | 502 | 上游服务异常。 |
|