集成指南
本文档介绍如何在 Web 应用中集成 TUIRoomKit 研讨会场景。该场景支持主持人、嘉宾与万级以上观众的实时互动,具备超低延时观看和高性能的消息处理能力。
标准会议与研讨会有何不同?
标准会议(Conference):适用于中小规模的多人协作场景,所有参与者均具有平等的音视频权限,支持宫格、演讲者等多种布局切换,并提供屏幕共享、成员管理等完整互动能力。
研讨会(Webinar):专为大型直播演讲设计,支持无上限观众进房观看。观众可举手申请上台成为嘉宾后参与讨论,且系统针对万人级互动场景优化了消息并发性能,满足更专业的演讲互动需求。
功能展示
研讨会开播端
支持主持人发起高清音视频推流与屏幕共享。当视频与屏幕共享同时开启时,支持对视频窗进行拖拽定位,灵活切换演讲布局。


研讨会嘉宾端
支持嘉宾开启麦克风进行实时语音讨论和分享。


研讨会观众端
支持观众无上限并发进房,以超低延迟观看实况并参与高频消息互动。支持观众通过"举手"功能向主持人申请变更为嘉宾。


前提条件
开通服务
SDKAppID: 应用标识,腾讯云基于
SDKAppID 完成计费统计。SDKSecretKey: 应用密钥,用于初始化配置文件的密钥信息。
注意:
研讨会场景基于底层的直播能力构建。请注意接入研讨会能力需要领取 TUILiveKit 体验版或开通 TUILiveKit 正式版,以确保相关功能的正常运行。
环境准备
Node.js: ≥ 18.19.1 (推荐使用官方 LTS 版本)。
Vue: ≥ 3.4.21。
现代浏览器:支持 WebRTC APIs 的现代浏览器。
设备:摄像头、麦克风、扬声器。
快速接入
步骤1:安装项目依赖
在您的业务项目中安装以下依赖。
npm install @tencentcloud/roomkit-web-vue3@5 tuikit-atomicx-vue3@5.4.1 @tencentcloud/uikit-base-component-vue3 @tencentcloud/universal-api
pnpm install @tencentcloud/roomkit-web-vue3@5 tuikit-atomicx-vue3@5.4.1 @tencentcloud/uikit-base-component-vue3 @tencentcloud/universal-api
yarn add @tencentcloud/roomkit-web-vue3@5 tuikit-atomicx-vue3@5.4.1 @tencentcloud/uikit-base-component-vue3 @tencentcloud/universal-api
步骤2:引用 TUIRoomKit 组件
<template><UIKitProvider theme="light" language="zh-CN"><ConferenceMainView></ConferenceMainView></UIKitProvider></template><script setup lang="ts">import { UIKitProvider } from '@tencentcloud/uikit-base-component-vue3';import { ConferenceMainView } from '@tencentcloud/roomkit-web-vue3';</script>
步骤3:登录
登录是使用 TUIRoomKit 一切功能的基础。通常建议在您的业务系统完成鉴权(用户登录您的 Web 页面)后,立即调用
conference.login 方法登录 TUIRoomKit。调用 conference.login 完成鉴权后,建议同步调用 conference.setSelfInfo 来设置当前用户的展示昵称和头像,这些信息将在随后的参会者视频区域和成员列表中展示。注意:
配置代码中,需要填入 UserSig。在正式的生产环境中,建议在您的服务端生成 UserSig,在需要 UserSig 时由您的客户端向业务服务器发起请求获取动态 UserSig 来进行鉴权。详见 正式运行阶段如何计算 UserSig。
import { onMounted } from 'vue';import { conference } from '@tencentcloud/roomkit-web-vue3';// 注意:以下参数请替换为您真实的业务数据和控制台获取的 SDKAppIDconst SDKAppID = 0;const userId = 'your_user_id';const userSig = 'your_dynamic_user_sig';const userName = '用户展示昵称';onMounted(async () => {try {// 1. 执行 SDK 登录await conference.login({sdkAppId: SDKAppID,userId,userSig,});// 2. (可选)设置个人信息await conference.setSelfInfo({userName,avatarUrl: 'https://your-avatar-url.com/image.png',});} catch (error) {console.error('TUIRoomKit 登录失败:', error);}});
接入问题:登录与进房分属不同路由页面如何监听登录成功的状态?
当登录页面与进房页面是两个独立路由时,进房页面加载时
conference.login 登录逻辑可能尚未执行。推荐通过 watch 监听 loginUserInfo.value?.userId,该字段非空即视为 TUIRoomKit 登录成功。import { watch } from 'vue';import { useLoginState } from 'tuikit-atomicx-vue3/room';import { conference, RoomType } from '@tencentcloud/roomkit-web-vue3';const { loginUserInfo } = useLoginState();watch(() => loginUserInfo.value?.userId, async (userId) => {if (userId) {await conference.joinRoom({ roomId: 'webinar_123456', roomType: RoomType.Webinar });}}, { immediate: true });
步骤4:创建研讨会
创建研讨会所需要的房间号(roomId)是会议的核心标识,由您的业务系统自行生成与维护(需保证全局唯一)。请根据您的实际业务场景,选择适合的创建研讨会的方式:
场景一:客户端发起研讨会
适用场景:主持人在客户端直接发起一场新的研讨会。
实现方式:由客户端生成或向业务后台申请一个唯一的房间号,随后由主持人调用
conference.createAndJoinRoom 创建并直接进入研讨会房间。其他参与者请参见 步骤5 调用 conference.joinRoom 接口加入。import { conference, RoomType } from '@tencentcloud/roomkit-web-vue3';const startWebinar = async () => {await conference.createAndJoinRoom({roomId: 'webinar_123456', // 请替换为您真实的 roomId,建议研讨会场景的 roomId 统一以 'webinar_' 开头roomType: RoomType.Webinar,options: {roomName: '我的研讨会',},});};
场景二:服务端创建研讨会
适用场景:政务、医疗、大型企业 OA 等强管控场景,由业务服务端统一管理研讨会的创建。
实现方式:会议的创建动作完全由您的业务服务端发起,调用腾讯云的 服务端 REST API 创建房间。创建时
RoomType 必须为 "Live",并通过 SeatTemplate 字段指定上麦模版。POST /v4/live_engine_http_srv/create_room{"RoomInfo": {"RoomId": "webinar_123456","RoomType": "Live","RoomName": "我的研讨会","Owner_Account": "host-user-id","SeatTemplate": "VideoLandscapeAudioMix10Seats","IsPublicVisible": false}}
SeatTemplate 上麦模版参数说明:模版值 | 适用端 | 说明 |
VideoLandscapeAudioMix10Seats | Web 桌面端 | 横屏视频布局,最多 10 个上麦席位 |
VideoPortraitAudioMix10Seats | 移动端 | 竖屏视频布局,最多 10 个上麦席位 |
步骤5:加入研讨会
注意:
调用
joinRoom 后默认以观众身份进入。观众可通过"举手"功能向主持人申请上台,或由主持人/管理员在成员列表中直接将其设置为嘉宾。暂不支持通过参数直接指定以嘉宾身份加入。import { conference, RoomType } from '@tencentcloud/roomkit-web-vue3';const joinWebinar = async (sharedRoomId: string) => {await conference.joinRoom({roomId: sharedRoomId, // 请替换为您真实的 roomIdroomType: RoomType.Webinar,});};
步骤6:离开与解散房间
TUIRoomKit 已在界面上内置了离开和解散房间的功能,用户可直接点击界面上的「离开房间」或「解散房间」按钮完成操作。
如果您需要在客户端通过代码主动触发离开或解散,可调用以下接口。
场景一:主动离开房间
参与者和房主均可调用
leaveRoom() 离开研讨会,调用后不影响其他成员,房间继续存在。import { conference } from '@tencentcloud/roomkit-web-vue3';await conference.leaveRoom();
说明:
场景二:主动解散房间
房主调用
endRoom() 后,房间内所有成员均会收到房间已解散的通知。import { conference } from '@tencentcloud/roomkit-web-vue3';await conference.endRoom();
说明:
endRoom() 必须由房主在成功进入房间后才能调用。非房主身份或在尚未进入房间的状态下调用会报错。步骤7:监听房间状态
在真实的音视频会议场景中,房间状态可能会因为各种不可控因素发生变化(例如:房主主动解散了会议、账号在其他设备登录、或者网络异常导致进房失败)。
TUIRoomKit 内部会自动处理底层音视频资源的销毁和 UI 提示,但界面的路由跳转必须由您的业务层来接管。因此,强烈建议您在会议组件挂载(
onMounted)时注册状态监听,并在组件卸载(onUnmounted)时及时销毁监听。<template><ConferenceMainView></ConferenceMainView></template><script setup lang="ts">import { ref, onMounted, onUnmounted } from 'vue';import { ConferenceMainView, conference, RoomEvent } from '@tencentcloud/roomkit-web-vue3';const backToHome = () => {};const backToLogin = () => {};onMounted(() => {conference.on(RoomEvent.ROOM_DISMISS, backToHome);conference.on(RoomEvent.ROOM_LEAVE, backToHome);conference.on(RoomEvent.ROOM_ERROR, backToHome);conference.on(RoomEvent.KICKED_OUT, backToHome);conference.on(RoomEvent.KICKED_OFFLINE, backToLogin);conference.on(RoomEvent.USER_SIG_EXPIRED, backToLogin);});onUnmounted(() => {conference.off(RoomEvent.ROOM_DISMISS, backToHome);conference.off(RoomEvent.ROOM_LEAVE, backToHome);conference.off(RoomEvent.ROOM_ERROR, backToHome);conference.off(RoomEvent.KICKED_OUT, backToHome);conference.off(RoomEvent.KICKED_OFFLINE, backToLogin);conference.off(RoomEvent.USER_SIG_EXPIRED, backToLogin);});</script>
事件 | 触发时机 | 推荐处理 |
RoomEvent.ROOM_DISMISS | 房间被解散,对所有成员触发 | 返回首页或会议列表 |
RoomEvent.ROOM_LEAVE | 用户点击 TUIRoomKit 界面上的「离开」按钮 | 返回首页或会议列表 |
RoomEvent.ROOM_ERROR | 进房失败或房间内发生未处理的错误 | 返回首页或会议列表 |
RoomEvent.KICKED_OUT | 被房主踢出房间 | 返回首页或会议列表 |
RoomEvent.KICKED_OFFLINE | 同一账号在其他设备登录,当前设备被强制下线 | 跳转登录页 |
RoomEvent.USER_SIG_EXPIRED | UserSig 已过期 | 跳转登录页 |
启动项目
npm run dev
pnpm run dev
yarn run dev
启动成功后,请在浏览器中打开调试地址(通常为 http://localhost:5173)访问应用。您将看到如下所示的研讨会界面:


下一步
在完成基础集成后,您可以根据业务需求进一步定制 UI 界面。
配置主题及语言
UIKitProvider 参数 | 可选值 | 默认值 |
theme | "light" | "dark" | "light" |
language | "zh-CN" | "en-US" | "en-US" |
<UIKitProvider theme="light" language="zh-CN"><router-view /></UIKitProvider><script setup lang="ts">import { UIKitProvider } from '@tencentcloud/uikit-base-component-vue3';</script>
修改房间分享链接
TUIRoomKit 默认使用当前页面地址作为房间分享链接。如您需要修改链接地址,可调用
conference.setFeatureConfig 更新分享链接。import { conference } from '@tencentcloud/roomkit-web-vue3';// 在 conference.createAndJoinRoom / conference.joinRoom 成功之后立即调用,确保 roomId 已知const roomId = 'webinar_123456';conference.setFeatureConfig({shareLink: `https://your-domain.com/room?roomId=${roomId}`,});
常见问题
研讨会房间有自动解散机制吗?
有用户进入过研讨会房间后,房间持续空置超过一定时长(默认 30 分钟)且无人进房,触发自动解散。
房主调用接口离开房间后,持续超过一定时长(默认 10 分钟)未重新进房,触发自动解散。该时长支持调整,配置区间为 [2 分钟,12 小时]。
房主因心跳超时掉线后,持续超过一定时长(默认 10 分钟)未恢复心跳进房,触发自动解散。该时长支持调整,配置区间为 [2 分钟,12 小时]。
为避免意外触发自动解散,建议在研讨会实际结束时,通过以下任一方式主动销毁房间:
界面操作:主持人点击 TUIRoomKit 界面上的「解散房间」按钮;
客户端 API:调用
conference.endRoom() 方法;服务端 API:通过 REST API 进行远程销毁。
多个设备能否使用同一个 userId 同时加入同一场研讨会?
不支持。TUIRoomKit 不允许同一 userId 在多个设备上同时进入同一房间。
互踢机制:若后到的设备使用相同 userId 尝试进房,先前已在房内的设备会被强制下线(踢出)。
解决方案:如需实现多端(如手机、PC)同时加入研讨会,请确保为每个设备分配唯一的 userId。
在本地开发时使用正常,但部署到线上环境后无法正常采集用户的摄像头或麦克风设备?
原因分析:浏览器出于安全和隐私保护的考虑,对音视频设备(麦克风、摄像头)的采集有着严格限制。只有在安全环境下,采集操作才会被允许。安全环境协议包括:https://、localhost、file:// 等。HTTP 协议被视为不安全,浏览器会默认禁止访问媒体设备。
解决方案:若您在本地(localhost)测试一切正常,但部署后出现采集失败,请检查网页是否部署在 HTTP 协议上。线上部署需使用 HTTPS 并配置有效证书,否则浏览器将限制对摄像头和麦克风的采集权限。
相关资源:更多关于 URL 域名及协议的限制详情,请参见 URL 域名及协议限制说明。
是否支持使用 iframe 集成?
支持。使用 iframe 集成 TUIRoomKit 时, 需要在 iframe 标签中配置 allow 属性以授予必要的浏览器权限(麦克风、摄像头、屏幕共享、全屏等),示例如下:
// 开启麦克风、摄像头、屏幕分享、全屏权限<iframe src="https://your-domain.com/index.html" allow="microphone; camera; display-capture; display; fullscreen;" />
是否支持设置内网代理?
// 请在进房前设置内网代理参数import TUIRoomEngine from '@tencentcloud/tuiroom-engine-js';import { useRoomEngine } from 'tuikit-atomicx-vue3/room';const { roomEngine } = useRoomEngine();TUIRoomEngine.once('ready', () => {const trtcCloud = roomEngine.instance?.getTRTCCloud();trtcCloud.callExperimentalAPI(JSON.stringify({api: 'setNetworkProxy',params: {websocketProxy: "wss://proxy.example.com/ws/",turnServer: [{url: '14.3.3.3:3478',username: 'turn',credential: 'turn',}],iceTransportPolicy: 'relay',},}));});