hyapp-server/docs/flutter对接/进房接口Flutter对接.md
2026-07-03 10:43:34 +08:00

8.5 KiB
Raw Permalink Blame History

进房接口 Flutter 对接

接口地址

POST /api/v1/rooms/join
Authorization: Bearer <access_token>
Content-Type: application/json

新版本进房默认使用 response_mode=litefull 仍保留给旧客户端兼容,不建议新 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/joinbody 传 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 不是 litefull
UNAUTHORIZED 401 未登录或 token 无效。
PROFILE_REQUIRED 403 用户资料未补全。
PERMISSION_DENIED 403 密码错误、被踢/被禁等权限问题。
ROOM_CLOSED 409 房间已关闭;非房主不能进入。
NOT_FOUND 404 房间不存在。
UPSTREAM_ERROR 502 上游服务异常。