以下时序图展示了房间从创建到销毁的主要流程。
一、前提条件
用户已经通过 useLoginState 完成登录鉴权,请参考 接入概览。
三、步骤1:导入 useRoomState
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom, joinRoom, updateRoomInfo, leaveRoom, endRoom, currentRoom,} = useRoomState();import { useRoomState } from 'tuikit-atomicx-react/room';const { createAndJoinRoom, joinRoom, updateRoomInfo, leaveRoom, endRoom, currentRoom,} = useRoomState();
四、步骤2:创建房间
请根据你的业务场景,选择适合的创建房间方式。
注意:创建房间时指定的 roomId 建议由业务后台生成并下发,以确保同一场会议在你的业务系统中具备稳定且唯一的标识。
五、场景一:客户端发起快速会议
适用场景:用户在客户端点击“快速会议”,需要立即发起并进入一个房间,例如临时沟通、IM 会话内发起会议。
实现方式:调用 createAndJoinRoom 创建并进入房间。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({ roomId: 'YOUR_ROOM_ID', // 必填:建议由业务后台生成的唯一标识 options: { roomName: '项目进度周会', // 选填:房间展示名称 },});import { useRoomState } from 'tuikit-atomicx-react/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({ roomId: 'YOUR_ROOM_ID', // 必填:建议由业务后台生成的唯一标识 options: { roomName: '项目进度周会', // 选填:房间展示名称 },});
如果你需要限制入会范围,也可以在快速会议场景下创建密码房间。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({ roomId: 'YOUR_ROOM_ID', // 必填:建议由业务后台生成的唯一标识 options: { roomName: '项目进度周会', // 选填:房间展示名称 password: '123', // 选填:开启密码入会模式 },});import { useRoomState } from 'tuikit-atomicx-react/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({ roomId: 'YOUR_ROOM_ID', // 必填:建议由业务后台生成的唯一标识 options: { roomName: '项目进度周会', // 选填:房间展示名称 password: '123', // 选填:开启密码入会模式 },});
注意:说明:
注意:创建者在调用 createAndJoinRoom 时会自动加入房间,无需额外输入密码。
六、场景二:客户端预约会议
适用场景:适用于需要在未来特定时间召开的会议(例如团队周会、线上培训等)。用户可在客户端提前设定会议标题、时间及受邀参会成员。
实现方式:由客户端生成或向业务后台申请一个唯一的房间号,并配合会议时间等参数调用 scheduleRoom 接口提交预定。预定成功后,会议信息将同步至参与者的会议列表中。更多客户端预订会议能力请参考 无 UI 集成 > 预订房间。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { scheduleRoom } = useRoomState();const createSchedule = async () => { try { // roomId 限制:字符串类型,必传参数,建议由业务后台生成保证 roomId 唯一性。 const roomId = '123456'; // 注意:时间戳单位必须为 **秒** (Date.getTime() 获取的是毫秒,需除以 1000) const startTime = Math.floor(new Date().getTime() / 1000) + 3600; // 1小时后开始 const duration = 1800; // 30分钟 const options = { roomName: '产品需求评审会', scheduleStartTime: startTime, // 单位:秒 scheduleEndTime: startTime + duration, // 单位:秒 scheduleAttendees: ['userA', 'userB'], // 邀请参会成员ID列表 password: '123', // 可选:设置入会密码 }; await scheduleRoom({ roomId, options }); } catch (error) { console.error('预定失败', error); }};import { useRoomState } from 'tuikit-atomicx-react/room';const { scheduleRoom } = useRoomState();const createSchedule = async () => { try { // roomId 限制:字符串类型,必传参数,建议由业务后台生成保证 roomId 唯一性。 const roomId = '123456'; // 注意:时间戳单位必须为 **秒** (Date.getTime() 获取的是毫秒,需除以 1000) const startTime = Math.floor(new Date().getTime() / 1000) + 3600; // 1小时后开始 const duration = 1800; // 30分钟 const options = { roomName: '产品需求评审会', scheduleStartTime: startTime, // 单位:秒 scheduleEndTime: startTime + duration, // 单位:秒 scheduleAttendees: ['userA', 'userB'], // 邀请参会成员ID列表 password: '123', // 可选:设置入会密码 }; await scheduleRoom({ roomId, options }); } catch (error) { console.error('预定失败', error); }};
七、场景三:服务端创建会议
适用场景:政务、医疗、大型企业 OA 等强管控场景。
实现方式:会议的创建动作完全由你的业务服务端发起,调用腾讯云的 服务端 REST API 创建房间。
POST /v4/room_engine_http_srv/create_room{ "roomId": "your-room-id", "roomName": "会议名称", "startTime": 1710000000, "endTime": 1710003600, "invitees": ["userId1", "userId2"]}
八、步骤3:加入房间
请根据你是否确定房间已经存在,选择不同的加入方式。
九、场景一:确定房间已经存在
适用场景:
·用户从房间列表进入会议。
·用户通过会议邀请链接进入会议。
·房间已经由发起人或服务端创建完成。
实现方式:直接调用 joinRoom。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { joinRoom } = useRoomState();await joinRoom({ roomId: 'YOUR_ROOM_ID',});import { useRoomState } from 'tuikit-atomicx-react/room';const { joinRoom } = useRoomState();await joinRoom({ roomId: 'YOUR_ROOM_ID',});
如果房间开启了密码保护,调用 joinRoom 时可能返回以下错误码:
·TUIErrorCode.ERR_NEED_PASSWORD:表示该房间需要密码。建议由业务侧弹出密码输入框,用户输入后再次调用 joinRoom。
·TUIErrorCode.ERR_WRONG_PASSWORD:表示密码错误。建议提示用户重新输入密码,再次调用 joinRoom。
在无 UI 接入场景下,密码输入弹窗和错误提示需由业务层自行实现。
十、场景二:只知道 roomId,但不确定房间是否已经存在
适用场景:双向对等发起的场景,例如在线问诊、视频面试、1v1 视频客服等,双方只知道同一个 roomId,但无法预先确定谁会先进入。
实现方式:直接调用 createAndJoinRoom。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({ roomId: 'YOUR_ROOM_ID', options: { roomName: '业务沟通房间', },});import { useRoomState } from 'tuikit-atomicx-react/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({ roomId: 'YOUR_ROOM_ID', options: { roomName: '业务沟通房间', },});
注意:说明:
注意:createAndJoinRoom 支持“房间不存在则创建,房间已存在则加入”的进房方式,适合无法预先判断房间状态的业务场景。
十一、步骤4:更新房间信息
房主可以在进入房间后调用 updateRoomInfo 更新房间名称和密码。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { updateRoomInfo } = useRoomState();await updateRoomInfo({ roomId: 'YOUR_ROOM_ID', options: { roomName: '新的房间名称', password: '234567', },});import { useRoomState } from 'tuikit-atomicx-react/room';const { updateRoomInfo } = useRoomState();await updateRoomInfo({ roomId: 'YOUR_ROOM_ID', options: { roomName: '新的房间名称', password: '234567', },});
注意:说明:
注意:房主必须已经在房间内才能调用 updateRoomInfo。如果房主已经离开房间,需要先重新加入房间。
十二、步骤5:离开房间与解散房间
房间内的退出操作分为“离开房间”和“解散房间”两种,请根据业务目标选择合适的接口。
十三、场景一:离开房间
适用场景:当前用户仅需退出房间,不影响其他成员继续留在房间内。
实现方式:调用 leaveRoom。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { currentRoom, leaveRoom } = useRoomState();if (!currentRoom.value) { return;}await leaveRoom();import { useRoomState } from 'tuikit-atomicx-react/room';const { currentRoom, leaveRoom } = useRoomState();if (!currentRoom) { return;}await leaveRoom();
十四、场景二:解散房间
适用场景:房主需要结束当前会议,并使所有成员退出房间。
实现方式:调用 endRoom。
Vue3Reactimport { useRoomState } from 'tuikit-atomicx-vue3/room';const { currentRoom, endRoom } = useRoomState();if (!currentRoom.value) { return;}await endRoom();import { useRoomState } from 'tuikit-atomicx-react/room';const { currentRoom, endRoom } = useRoomState();if (!currentRoom) { return;}await endRoom();
注意:说明:
十五、步骤6:处理房间状态事件变更
在房间生命周期中,业务层通常需要处理房间被解散、用户被踢出等事件。建议在组件挂载时注册事件监听,在组件销毁时移除监听。
十六、处理房间被解散事件
普通用户可通过监听 RoomEvent.onRoomEnded 处理房间被房主解散后的业务交互。
Vue3Reactimport { onMounted, onUnmounted } from 'vue';import { useRoomState, RoomEvent } from 'tuikit-atomicx-vue3/room';import { TUIMessageBox } from '@tencentcloud/uikit-base-component-vue3';const { subscribeEvent, unsubscribeEvent } = useRoomState();function onRoomEnded() { TUIMessageBox.alert({ title: '通知', content: '房主已解散房间', });}onMounted(() => { subscribeEvent(RoomEvent.onRoomEnded, onRoomEnded);});onUnmounted(() => { unsubscribeEvent(RoomEvent.onRoomEnded, onRoomEnded);});import { useEffect } from 'react';import { useRoomState, RoomEvent } from 'tuikit-atomicx-react/room';import { MessageBox } from '@tencentcloud/uikit-base-component-react';const { subscribeEvent, unsubscribeEvent } = useRoomState();function onRoomEnded() { MessageBox.alert({ title: '通知', content: '房主已解散房间', });}useEffect(() => { subscribeEvent(RoomEvent.onRoomEnded, onRoomEnded); return () => { unsubscribeEvent(RoomEvent.onRoomEnded, onRoomEnded); };}, []);
十七、处理用户被踢出房间事件
普通用户可通过监听 RoomParticipantEvent.onKickedFromRoom 处理用户被踢出房间后的业务交互。
Vue3Reactimport { onMounted, onUnmounted } from 'vue';import { useRoomParticipantState, RoomParticipantEvent, KickedOutOfRoomReason,} from 'tuikit-atomicx-vue3/room';import { TUIMessageBox } from '@tencentcloud/uikit-base-component-vue3';const { subscribeEvent, unsubscribeEvent } = useRoomParticipantState();function onKickedFromRoom({ reason,}: { reason: KickedOutOfRoomReason; message: string;}) { let notice = ''; switch (reason) { case KickedOutOfRoomReason.KickedByAdmin: notice = '你已被房主移出房间'; break; case KickedOutOfRoomReason.ReplacedByAnotherDevice: notice = '你的账号已在其他设备登录'; break; case KickedOutOfRoomReason.KickedByServer: notice = '你已被服务器移出房间'; break; case KickedOutOfRoomReason.ConnectionTimeout: notice = '网络连接超时,正在退出房间'; break; case KickedOutOfRoomReason.InvalidStatusOnReconnect: notice = '房间已解散或你在离线期间已被移出'; break; case KickedOutOfRoomReason.RoomLimitExceeded: notice = '房间人数已达上限,无法加入'; break; default: notice = '你已被移出房间'; break; } TUIMessageBox.alert({ title: '通知', content: notice, });}onMounted(() => { subscribeEvent(RoomParticipantEvent.onKickedFromRoom, onKickedFromRoom);});onUnmounted(() => { unsubscribeEvent(RoomParticipantEvent.onKickedFromRoom, onKickedFromRoom);});import { useEffect } from 'react';import { useRoomParticipantState, RoomParticipantEvent, KickedOutOfRoomReason,} from 'tuikit-atomicx-react/room';import { MessageBox } from '@tencentcloud/uikit-base-component-react';const { subscribeEvent, unsubscribeEvent } = useRoomParticipantState();function onKickedFromRoom({ reason,}: { reason: KickedOutOfRoomReason; message: string;}) { let notice = ''; switch (reason) { case KickedOutOfRoomReason.KickedByAdmin: notice = '你已被房主移出房间'; break; case KickedOutOfRoomReason.ReplacedByAnotherDevice: notice = '你的账号已在其他设备登录'; break; case KickedOutOfRoomReason.KickedByServer: notice = '你已被服务器移出房间'; break; case KickedOutOfRoomReason.ConnectionTimeout: notice = '网络连接超时,正在退出房间'; break; case KickedOutOfRoomReason.InvalidStatusOnReconnect: notice = '房间已解散或你在离线期间已被移出'; break; case KickedOutOfRoomReason.RoomLimitExceeded: notice = '房间人数已达上限,无法加入'; break; default: notice = '你已被移出房间'; break; } MessageBox.alert({ title: '通知', content: notice, });}useEffect(() => { subscribeEvent(RoomParticipantEvent.onKickedFromRoom, onKickedFromRoom); return () => { unsubscribeEvent(RoomParticipantEvent.onKickedFromRoom, onKickedFromRoom); };}, []);
十八、场景最佳实践
下表总结了不同业务场景下的推荐接入方式。
| 业务场景 | 推荐做法 | 推荐接口/方式 |
| 临时沟通、即时会议 | 由发起人在客户端直接创建并进入房间,其他参会人拿到 roomId 后加入 | 发起人使用 createAndJoinRoom,参会人使用 joinRoom |
| 团队周会、培训、定期例会 | 由客户端提前预约会议,会议开始前在会议列表或详情页展示,开始后再入会 | 创建阶段参考 预定房间,入会阶段使用 joinRoom |
| 在线教育、医疗、政务、企业 OA 等由业务系统统一创建会议的场景 | 由业务系统提前分配 roomId,调用服务端接口创建房间,客户端在指定页面获取 roomId 调用 joinRoom 入会 | 由业务系统提前创建会议房间,客户端使用 joinRoom |
| 在线问诊、视频面试、1v1 客服 | 双方使用同一个业务标识作为 roomId,任意一方进入时都可直接尝试进房 | 使用 createAndJoinRoom |
十九、错误码速查
在无 UI SDK 接入场景下,建议你通过 try/catch 统一处理创建房间和加入房间时的常见错误。
TUIErrorCode 可从 tuikit-atomicx-vue3 导入:
Vue3Reactimport { TUIErrorCode } from 'tuikit-atomicx-vue3';import { TUIErrorCode } from 'tuikit-atomicx-react';
| 错误码名称 | 错误码值 | 常见触发场景 | 建议处理方式 |
| TUIErrorCode.ERR_NEED_PASSWORD | 100018 | 进入密码房间但未传入密码 | 由业务侧弹出密码输入框,用户输入后再次调用 joinRoom |
| TUIErrorCode.ERR_WRONG_PASSWORD | 100019 | 进入密码房间时传入的密码错误 | 提示用户密码错误,允许重新输入后再次调用 joinRoom |
| TUIErrorCode.ERR_ROOM_ID_NOT_EXIST | 100004 | 调用 joinRoom 时房间不存在 | 提示房间不存在;若属于双向发起场景,建议直接改用 createAndJoinRoom |
| TUIErrorCode.ERR_ROOM_USER_FULL | 100008 | 房间人数已达上限 | 提示房间人数已满,并引导用户稍后重试或联系房主 |
| TUIErrorCode.ERR_ROOM_ID_OCCUPIED | 100003 | 创建房间时使用的 roomId 已被占用 | 检查 roomId 生成策略;若业务允许“房间已存在则直接进入”,建议使用 createAndJoinRoom |
21、房间内已经没有用户但房间未被解散,房间是否会一直存在?
房间内连续 6 小时无用户进入时,后台将尝试回收房间。
22、房间内已经没有用户但房间未被解散,是否会产生费用消耗?
没有用户但是未被解散的房间仅占用套餐群组数,不产生分钟数消耗和额外费用消耗。
23、一个用户可以同时加入多个房间吗?
useRoomState 为单例接口,仅支持用户同时加入一个房间。
24、最多支持多少人同时加入房间?
房间内用户数量上限和你的套餐包相关,具体请查看 TUIRoomKit 套餐包说明。