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

252 lines
5.8 KiB
Markdown

# 关键修复:TUICallKit 初始化问题
## 问题描述
在使用 TUICallKit 组件时,出现以下错误:
```
API<getDeviceList>: init or login is not complete
TUICallEngine 初始化登录未完成
<ERROR_INIT_FAIL: -1201>
```
## 根本原因
TUICallKit 组件在挂载(mount)时会立即调用内部 API(如 `getDeviceList`),但此时 `TUICallKitServer.init()` 可能还没有完全完成初始化。
即使我们在代码中等待了 `await TUICallKitServer.init()`,组件内部的初始化仍需要额外的时间。
## 解决方案
### 方案 1: 增加等待时间(当前采用)
```typescript
// 1. 调用 init
await TUICallKitServer.init({
userID: res.userId,
userSig: res.userSig,
SDKAppID: res.sdkAppId
})
// 2. 等待 2 秒确保初始化完全完成
await new Promise(resolve => setTimeout(resolve, 2000))
// 3. 显示组件
isInitialized.value = true
// 4. 等待 DOM 更新
await nextTick()
// 5. 再等待 500ms
await new Promise(resolve => setTimeout(resolve, 500))
// 6. 发起通话
await TUICallKitServer.call({ ... })
```
### 方案 2: 不使用 TUICallKit 组件(备选)
如果方案 1 仍然有问题,可以考虑不使用 TUICallKit 组件,而是使用 div 容器:
```vue
<!-- 不使用组件 -->
<div v-else id="TUICallKit" class="tui-call-kit"></div>
```
然后 TUICallKit 会自动将 UI 渲染到这个 div 中。
## 当前实现
### 关键代码
```typescript
const startCall = async () => {
try {
initializing.value = true
statusText.value = '正在获取签名...'
// 1. 获取签名
const res = await getCallSignature({ ... })
statusText.value = '正在初始化通话组件...'
// 2. 初始化
await TUICallKitServer.init({
userID: res.userId,
userSig: res.userSig,
SDKAppID: res.sdkAppId
})
statusText.value = '等待初始化完成...'
// 3. 等待 2 秒(关键!)
await new Promise(resolve => setTimeout(resolve, 2000))
statusText.value = '初始化完成,准备发起通话...'
// 4. 显示组件
isInitialized.value = true
calling.value = true
// 5. 等待 DOM 更新
await nextTick()
// 6. 再等待 500ms
await new Promise(resolve => setTimeout(resolve, 500))
// 7. 发起通话
await TUICallKitServer.call({
userID: callInfo.value.userId,
type: TUICallType.VIDEO_CALL
})
feedback.msgSuccess('通话已发起,等待对方接听...')
} catch (error) {
// 错误处理
}
}
```
### 模板代码
```vue
<template>
<div class="video-call-container">
<!-- 初始化前显示等待界面 -->
<div v-if="!isInitialized" class="call-waiting">
<el-icon class="loading-icon"><VideoCamera /></el-icon>
<p>{{ statusText }}</p>
</div>
<!-- 初始化完成后显示容器 -->
<div v-else id="TUICallKit" class="tui-call-kit"></div>
</div>
</template>
```
## 时间线
```
0ms 用户点击"开始通话"
100ms 开始获取签名
500ms 签名获取完成
600ms 调用 TUICallKitServer.init()
1000ms init() Promise resolved
3000ms 等待 2000ms 完成(确保内部初始化完成)
3000ms 设置 isInitialized = true
3000ms Vue 开始渲染容器
3010ms nextTick() 完成
3510ms 等待 500ms 完成
3510ms 调用 TUICallKitServer.call()
3600ms 通话发起成功
```
## 为什么需要这么长的等待时间?
1. **TUICallKitServer.init() 的异步性**
- 虽然 Promise resolved,但内部可能还有异步操作
- 需要初始化 WebRTC、设备检测等
2. **设备枚举需要时间**
- `getDeviceList` 需要访问摄像头和麦克风
- 浏览器需要时间来枚举设备
3. **权限请求**
- 如果是首次访问,需要用户授权
- 授权过程是异步的
4. **组件渲染**
- Vue 的响应式更新需要时间
- DOM 操作需要时间
## 调试建议
### 1. 查看控制台日志
```typescript
console.log('1. 签名获取成功')
console.log('2. TUICallKit init 方法调用完成')
console.log('3. 等待完成,准备显示通话界面')
console.log('4. 准备发起通话')
console.log('5. 通话已发起')
```
### 2. 检查初始化状态
在浏览器控制台执行:
```javascript
// 检查 TUICallKitServer 状态
console.log(window.TUICallKitServer)
```
### 3. 监控设备访问
打开浏览器开发者工具 → Console,查看是否有设备访问相关的日志。
## 如果仍然失败
### 增加等待时间
如果 2 秒还不够,可以增加到 3 秒:
```typescript
await new Promise(resolve => setTimeout(resolve, 3000))
```
### 使用轮询检查
```typescript
// 轮询检查初始化状态
let retries = 0
const maxRetries = 20
while (retries < maxRetries) {
try {
// 尝试调用一个需要初始化的 API
await TUICallKitServer.call({ ... })
break
} catch (error) {
if (error.code === -1201) {
// 还没初始化完成,继续等待
await new Promise(resolve => setTimeout(resolve, 500))
retries++
} else {
throw error
}
}
}
```
### 联系技术支持
如果以上方法都不行,可能需要:
1. 检查腾讯云 TRTC 配置
2. 检查网络连接
3. 查看腾讯云控制台的错误日志
4. 联系腾讯云技术支持
## 参考资料
- [TUICallKit 初始化问题](https://cloud.tencent.com/document/product/647/78769#3a61f42b-e06f-49af-88bf-362d40025887)
- [初始化流程详解](./INITIALIZATION_GUIDE.md)
- [故障排查指南](./TROUBLESHOOTING.md)
## 更新日志
- 2024-03-02: 初始版本,等待时间 500ms + 300ms
- 2024-03-02: 增加等待时间到 2000ms + 500ms
- 2024-03-02: 添加 nextTick() 确保 DOM 更新
- 2024-03-02: 改用 div 容器而不是 TUICallKit 组件