本篇文档旨在指导开发者如何利用无 UI SDK 的 useRoomState 处理 Web 端房间的全生命周期。通过响应式状态管理,您可以灵活实现房间的创建、加入、信息同步及销毁逻辑,并精准捕获各类房间事件。
以下时序图展示了房间从创建到销毁的主要流程。


前提条件
注意:
异步性:
login 方法为异步执行。在单页应用中,建议通过监听 loginUserInfo.value?.userId 的变化来确保登录就绪,严禁在未确认登录状态时抢跑调用房间管理方法。单例约束:
useRoomState 采用单例设计,同一用户同一时刻仅支持存在于一个房间内。实现房间管理
步骤1:导入 useRoomState
import { useRoomState } from 'tuikit-atomicx-vue3/room';const {createAndJoinRoom,joinRoom,updateRoomInfo,leaveRoom,endRoom,currentRoom,} = useRoomState();
步骤2:创建房间
请根据您的业务场景,选择适合的创建房间方式。
注意:
创建房间时指定的
roomId 建议由业务后台生成并下发,以确保同一场会议在您的业务系统中具备稳定且唯一的标识。场景一:客户端发起快速会议
适用场景:用户在客户端点击“快速会议”,需要立即发起并进入一个房间,例如临时沟通、IM 会话内发起会议。
import { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({roomId: 'YOUR_ROOM_ID', // 必填:建议由业务后台生成的唯一标识options: {roomName: '项目进度周会', // 选填:房间展示名称},});
如果您需要限制入会范围,也可以在快速会议场景下创建密码房间。
import { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({roomId: 'YOUR_ROOM_ID', // 必填:建议由业务后台生成的唯一标识options: {roomName: '项目进度周会', // 选填:房间展示名称password: '123', // 选填:开启密码入会模式},});
说明:
创建者在调用
createAndJoinRoom 时会自动加入房间,无需额外输入密码。场景二:客户端预约会议
适用场景:适用于需要在未来特定时间召开的会议(例如团队周会、线上培训等)。用户可在客户端提前设定会议标题、时间及受邀参会成员。
实现方式:由客户端生成或向业务后台申请一个唯一的房间号,并配合会议时间等参数调用
scheduleRoom 接口提交预定。预定成功后,会议信息将同步至参与者的会议列表中。更多客户端预订会议能力请参考 无 UI 集成 > 预订房间。import { 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);}};
场景三:服务端创建会议
适用场景:政务、医疗、大型企业 OA 等强管控场景。
POST /v4/room_engine_http_srv/create_room{"roomId": "your-room-id","roomName": "会议名称","startTime": 1710000000,"endTime": 1710003600,"invitees": ["userId1", "userId2"]}
步骤3:加入房间
请根据您是否确定房间已经存在,选择不同的加入方式。
场景一:确定房间已经存在
适用场景:
用户从房间列表进入会议。
用户通过会议邀请链接进入会议。
房间已经由发起人或服务端创建完成。
import { useRoomState } from 'tuikit-atomicx-vue3/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,但无法预先确定谁会先进入。import { useRoomState } from 'tuikit-atomicx-vue3/room';const { createAndJoinRoom } = useRoomState();await createAndJoinRoom({roomId: 'YOUR_ROOM_ID',options: {roomName: '业务沟通房间',},});
说明:
createAndJoinRoom 支持“房间不存在则创建,房间已存在则加入”的进房方式,适合无法预先判断房间状态的业务场景。步骤4:更新房间信息
import { useRoomState } from 'tuikit-atomicx-vue3/room';const { updateRoomInfo } = useRoomState();await updateRoomInfo({roomId: 'YOUR_ROOM_ID',options: {roomName: '新的房间名称',password: '234567',},});
说明:
房主必须已经在房间内才能调用
updateRoomInfo。如果房主已经离开房间,需要先重新加入房间。步骤5:离开房间与解散房间
房间内的退出操作分为“离开房间”和“解散房间”两种,请根据业务目标选择合适的接口。
场景一:离开房间
适用场景:当前用户仅需退出房间,不影响其他成员继续留在房间内。
import { useRoomState } from 'tuikit-atomicx-vue3/room';const { currentRoom, leaveRoom } = useRoomState();if (!currentRoom.value) {return;}await leaveRoom();
场景二:解散房间
适用场景:房主需要结束当前会议,并使所有成员退出房间。
import { useRoomState } from 'tuikit-atomicx-vue3/room';const { currentRoom, endRoom } = useRoomState();if (!currentRoom.value) {return;}await endRoom();
说明:
leaveRoom 适用于“当前用户退出”,不会销毁房间。
endRoom 仅房主可调用,用于结束当前房间。
如果房主离开房间但未调用 endRoom,房间将继续存在,直到满足自动回收条件(连续 6 小时无用户)。
房主可以通过 transferOwner 将房主身份转移给其他用户。
步骤6:处理房间状态事件变更
在房间生命周期中,业务层通常需要处理房间被解散、用户被踢出等事件。建议在组件挂载时注册事件监听,在组件销毁时移除监听。
处理房间被解散事件
普通用户可通过监听
RoomEvent.onRoomEnded 处理房间被房主解散后的业务交互。import { 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);});
处理用户被踢出房间事件
普通用户可通过监听
RoomParticipantEvent.onKickedFromRoom 处理用户被踢出房间后的业务交互。import { 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);});
场景最佳实践
下表总结了不同业务场景下的推荐接入方式。
业务场景 | 推荐做法 | 推荐接口/方式 |
临时沟通、即时会议 | 由发起人在客户端直接创建并进入房间,其他参会人拿到 roomId 后加入 | 发起人使用 createAndJoinRoom,参会人使用 joinRoom |
团队周会、培训、定期例会 | 由客户端提前预约会议,会议开始前在会议列表或详情页展示,开始后再入会 | |
在线教育、医疗、政务、企业 OA 等由业务系统统一创建会议的场景 | 由业务系统提前分配 roomId,调用服务端接口创建房间,客户端在指定页面获取 roomId 调用 joinRoom 入会 | 由业务系统提前创建会议房间,客户端使用 joinRoom |
在线问诊、视频面试、1v1 客服 | 双方使用同一个业务标识作为 roomId,任意一方进入时都可直接尝试进房 | 使用 createAndJoinRoom |
错误码速查
在无 UI SDK 接入场景下,建议您通过
try/catch 统一处理创建房间和加入房间时的常见错误。TUIErrorCode 可从 tuikit-atomicx-vue3 导入:import { TUIErrorCode } from 'tuikit-atomicx-vue3';
错误码名称 | 错误码值 | 常见触发场景 | 建议处理方式 |
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 |
常见问题
房间内已经没有用户但房间未被解散,房间是否会一直存在?
房间内连续 6 小时无用户进入时,后台将尝试回收房间。
房间内已经没有用户但房间未被解散,是否会产生费用消耗?
没有用户但是未被解散的房间仅占用套餐群组数,不产生分钟数消耗和额外费用消耗。
一个用户可以同时加入多个房间吗?
useRoomState 为单例接口,仅支持用户同时加入一个房间。