8.2 KiB
8.2 KiB
TUICallKit 初始化流程详解
问题背景
TUICallKit 组件需要在完全初始化后才能使用,如果在初始化完成前渲染组件,会出现以下错误:
API<getDeviceList>: init or login is not complete
ERROR_INIT_FAIL: -1201
正确的初始化流程
1. 流程图
用户点击"视频通话"
↓
打开对话框(显示"准备通话...")
↓
用户点击"开始通话"
↓
获取腾讯云签名(显示"正在获取签名...")
↓
调用 TUICallKitServer.init()(显示"正在初始化通话组件...")
↓
等待 500ms 确保初始化完成
↓
设置 isInitialized = true(显示"初始化完成,准备发起通话...")
↓
渲染 TUICallKit 组件
↓
等待 300ms 让组件完全渲染
↓
调用 TUICallKitServer.call() 发起通话
↓
通话进行中
2. 关键代码实现
步骤 1: 状态管理
const isInitialized = ref(false) // 是否已初始化
const initializing = ref(false) // 是否正在初始化
const calling = ref(false) // 是否正在通话
const statusText = ref('准备通话...') // 状态提示文本
步骤 2: 条件渲染
<template>
<div class="video-call-container">
<!-- 初始化前显示等待界面 -->
<div v-if="!isInitialized" class="call-waiting">
<el-icon class="loading-icon" :size="60"><VideoCamera /></el-icon>
<p class="mt-4">{{ statusText }}</p>
<p class="text-gray-500">{{ callInfo.patientName }}</p>
</div>
<!-- 初始化完成后才显示 TUICallKit 组件 -->
<TUICallKit v-else class="tui-call-kit" />
</div>
</template>
步骤 3: 初始化逻辑
const startCall = async () => {
try {
initializing.value = true
// 1. 获取签名
statusText.value = '正在获取签名...'
const res = await getCallSignature({
diagnosis_id: callInfo.value.diagnosisId,
patient_id: callInfo.value.patientId
})
if (!res || !res.userSig) {
throw new Error('获取签名失败')
}
// 2. 初始化 TUICallKit
statusText.value = '正在初始化通话组件...'
await TUICallKitServer.init({
userID: res.userId,
userSig: res.userSig,
SDKAppID: res.sdkAppId
})
// 3. 等待初始化完全完成(重要!)
statusText.value = '初始化完成,准备发起通话...'
await new Promise(resolve => setTimeout(resolve, 500))
// 4. 设置初始化完成标志,触发组件渲染
isInitialized.value = true
calling.value = true
// 5. 等待组件渲染完成(重要!)
await new Promise(resolve => setTimeout(resolve, 300))
// 6. 发起通话
await TUICallKitServer.call({
userID: callInfo.value.userId,
type: TUICallType.VIDEO_CALL
})
feedback.msgSuccess('通话已发起,等待对方接听...')
} catch (error: any) {
console.error('启动通话失败:', error)
feedback.msgError(error.message || '启动通话失败')
isInitialized.value = false
calling.value = false
} finally {
initializing.value = false
}
}
关键点说明
1. 为什么需要等待?
// 等待 500ms 确保初始化完成
await new Promise(resolve => setTimeout(resolve, 500))
原因:
TUICallKitServer.init()是异步操作- 即使 Promise resolve 了,内部可能还有一些异步初始化
- 等待一小段时间确保所有初始化完全完成
2. 为什么需要两次等待?
// 第一次等待:初始化完成
await new Promise(resolve => setTimeout(resolve, 500))
isInitialized.value = true
// 第二次等待:组件渲染完成
await new Promise(resolve => setTimeout(resolve, 300))
await TUICallKitServer.call({ ... })
原因:
- 第一次等待:确保 TUICallKitServer 初始化完成
- 设置
isInitialized = true后,Vue 会渲染 TUICallKit 组件 - 第二次等待:确保 TUICallKit 组件完全渲染和挂载
- 然后才能调用
call()方法
3. 状态提示的作用
statusText.value = '正在获取签名...'
// ... 执行操作 ...
statusText.value = '正在初始化通话组件...'
// ... 执行操作 ...
statusText.value = '初始化完成,准备发起通话...'
作用:
- 让用户知道当前进度
- 提升用户体验
- 便于调试和排查问题
常见错误
错误 1: 过早渲染组件
// ❌ 错误做法
await TUICallKitServer.init({ ... })
isInitialized.value = true // 立即设置为 true
await TUICallKitServer.call({ ... }) // 可能失败
// ✅ 正确做法
await TUICallKitServer.init({ ... })
await new Promise(resolve => setTimeout(resolve, 500)) // 等待
isInitialized.value = true
await new Promise(resolve => setTimeout(resolve, 300)) // 再等待
await TUICallKitServer.call({ ... }) // 成功
错误 2: 没有条件渲染
<!-- ❌ 错误做法:组件一直存在 -->
<TUICallKit class="tui-call-kit" />
<!-- ✅ 正确做法:条件渲染 -->
<TUICallKit v-if="isInitialized" class="tui-call-kit" />
错误 3: 没有错误处理
// ❌ 错误做法:没有 try-catch
await TUICallKitServer.init({ ... })
isInitialized.value = true
// ✅ 正确做法:完整的错误处理
try {
await TUICallKitServer.init({ ... })
await new Promise(resolve => setTimeout(resolve, 500))
isInitialized.value = true
} catch (error) {
console.error('初始化失败:', error)
isInitialized.value = false
feedback.msgError('初始化失败')
}
调试技巧
1. 添加日志
console.log('1. 开始获取签名')
const res = await getCallSignature({ ... })
console.log('2. 签名获取成功:', res)
console.log('3. 开始初始化')
await TUICallKitServer.init({ ... })
console.log('4. 初始化完成')
console.log('5. 等待初始化稳定')
await new Promise(resolve => setTimeout(resolve, 500))
console.log('6. 等待完成')
console.log('7. 设置初始化标志')
isInitialized.value = true
console.log('8. 标志已设置')
console.log('9. 等待组件渲染')
await new Promise(resolve => setTimeout(resolve, 300))
console.log('10. 组件渲染完成')
console.log('11. 发起通话')
await TUICallKitServer.call({ ... })
console.log('12. 通话已发起')
2. 监控状态变化
watch(isInitialized, (newVal) => {
console.log('isInitialized 变化:', newVal)
})
watch(calling, (newVal) => {
console.log('calling 变化:', newVal)
})
3. 检查初始化状态
在浏览器控制台执行:
// 检查 TUICallKitServer 是否已初始化
console.log('TUICallKitServer:', window.TUICallKitServer)
时序图
时间轴 →
0ms 用户点击"开始通话"
↓
100ms 获取签名开始
↓
500ms 获取签名完成
↓
600ms TUICallKitServer.init() 开始
↓
1000ms TUICallKitServer.init() 完成
↓
1500ms 等待 500ms 完成(确保初始化稳定)
↓
1500ms 设置 isInitialized = true
↓
1500ms Vue 开始渲染 TUICallKit 组件
↓
1800ms 等待 300ms 完成(确保组件渲染完成)
↓
1800ms 调用 TUICallKitServer.call()
↓
2000ms 通话发起成功
最佳实践
-
总是使用条件渲染
<TUICallKit v-if="isInitialized" /> -
总是等待初始化完成
await TUICallKitServer.init({ ... }) await new Promise(resolve => setTimeout(resolve, 500)) -
总是等待组件渲染
isInitialized.value = true await new Promise(resolve => setTimeout(resolve, 300)) -
总是添加错误处理
try { // 初始化逻辑 } catch (error) { // 错误处理 isInitialized.value = false } -
总是提供状态反馈
statusText.value = '正在初始化...'