Files
zyt/admin/INITIALIZATION_GUIDE.md
T
2026-03-04 15:32:30 +08:00

8.2 KiB
Raw Blame History

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  通话发起成功

最佳实践

  1. 总是使用条件渲染

    <TUICallKit v-if="isInitialized" />
    
  2. 总是等待初始化完成

    await TUICallKitServer.init({ ... })
    await new Promise(resolve => setTimeout(resolve, 500))
    
  3. 总是等待组件渲染

    isInitialized.value = true
    await new Promise(resolve => setTimeout(resolve, 300))
    
  4. 总是添加错误处理

    try {
      // 初始化逻辑
    } catch (error) {
      // 错误处理
      isInitialized.value = false
    }
    
  5. 总是提供状态反馈

    statusText.value = '正在初始化...'
    

参考资料