8.5 KiB
8.5 KiB
进房接口 Flutter 对接
接口地址
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。 |
请求示例:
{
"room_id": "lalu_abc123",
"command_id": "cmd_join_room_lalu_abc123_10001_1778000001000",
"role": "audience",
"password": "",
"response_mode": "lite"
}
也支持 query 参数:
POST /api/v1/rooms/join?response_mode=lite
Flutter 建议放在 body 里,避免调用层漏拼 query。
返回值
统一外壳:
{
"code": "OK",
"message": "ok",
"request_id": "req_xxx",
"data": {}
}
成功返回示例:
{
"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 执行:
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 出来后异步补齐。 |
后置资料接口
进房首屏出来后,再按需要异步拉展示资料:
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。 |
返回值:
{
"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
}
]
}
}
当前用户自己的装扮也可以后置拉:
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 | 上游服务异常。 |