252 lines
5.8 KiB
Markdown
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 组件
|