# 最终问题总结和解决方案 ## 🎉 进展 ### 已解决的问题 1. ✅ 语法错误已修复 2. ✅ 按钮事件可以触发 3. ✅ 录音功能可以启动 4. ✅ 录音文件可以生成 5. ✅ duration/fileSize undefined 问题已绕过 ### 当前问题 #### 问题1: WebSocket 连接不稳定 ``` 09:19:33.273 🔌 WebSocket 状态:0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED 09:20:28.752 ⭕ 录音已停止 WebSocket... 09:20:28.753 等待重新连接 WebSocket 连接... 09:20:28.907 WebSocket onOpen:[Object] {} ``` **原因**: - WebSocket 在录音过程中断开了 - 触发了自动重连机制 - 重连后才开始发送数据 **影响**: - 延迟了数据发送 - 可能导致超时 #### 问题2: 服务器还是 60 秒超时 ``` 09:21:29.115 📥 消息内容:{"type":"error","msg":"idle timeout"} ``` **原因**: - 服务器配置可能没有生效 - 或者服务器没有重启 ## 🔧 解决方案 ### 方案1: 确保服务器配置生效(最重要) #### 步骤1: 检查服务器 .env 文件 ```bash # 在服务器上执行 cat lover/.env ``` 应该看到: ``` VOICE_CALL_IDLE_TIMEOUT=120 ``` #### 步骤2: 确认服务器已重启 ```bash # 停止旧进程 pkill -f "uvicorn.*main:app" # 确认进程已停止 ps aux | grep uvicorn # 启动新进程 cd /path/to/lover uvicorn main:app --host 0.0.0.0 --port 30101 --reload ``` #### 步骤3: 验证配置 启动后,服务器应该加载新的配置。可以在服务器日志中看到。 ### 方案2: 修复 WebSocket 连接稳定性 #### 问题分析 WebSocket 在录音过程中断开,可能的原因: 1. 网络不稳定 2. 服务器主动断开(因为超时) 3. 客户端没有发送心跳 #### 解决方案A: 添加心跳机制 在 `phone.vue` 中添加心跳: ```javascript data() { return { heartbeatTimer: null } }, connectWebSocket() { // ... 原有代码 ... this.socketTask.onOpen((res) => { console.log('WebSocket onOpen:', res) this.startTimer() // 启动心跳 this.startHeartbeat() }) }, startHeartbeat() { // 清除旧的心跳 if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer) } // 每 30 秒发送一次心跳 this.heartbeatTimer = setInterval(() => { if (this.socketTask && this.socketTask.readyState === 1) { console.log('💓 发送心跳') this.socketTask.send({ data: 'ping', success: () => { console.log('✅ 心跳发送成功') }, fail: (err) => { console.error('❌ 心跳发送失败:', err) } }) } }, 30000) // 30 秒 }, stopCall() { // ... 原有代码 ... // 停止心跳 if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer) } } ``` #### 解决方案B: 增加 WebSocket 连接检查 在发送数据前,确保 WebSocket 已连接: ```javascript async sendAudioInChunks(audioData) { // 检查 WebSocket 状态 if (!this.socketTask || this.socketTask.readyState !== 1) { console.error('❌ WebSocket 未连接,等待重连...') // 等待最多 5 秒 for (let i = 0; i < 50; i++) { await new Promise(resolve => setTimeout(resolve, 100)) if (this.socketTask && this.socketTask.readyState === 1) { console.log('✅ WebSocket 已重连') break } } // 如果还是未连接,放弃 if (!this.socketTask || this.socketTask.readyState !== 1) { uni.showToast({ title: 'WebSocket 连接失败', icon: 'none' }) return } } // 继续原有逻辑... } ``` ### 方案3: 临时增加客户端等待时间 如果服务器配置无法立即修改,可以临时在客户端增加等待: ```javascript // 在 sendAudioInChunks 中 const chunkDelay = 200 // 从 100ms 增加到 200ms ``` 这样可以延长发送时间,减少超时的可能性。 ## 📊 当前状态分析 ### 时间线 ``` 09:19:28 - 开始录音 09:19:33 - 停止录音(录音 5 秒) 09:19:33 - WebSocket 状态检查 09:20:28 - WebSocket 断开并重连(约 55 秒后) 09:20:28 - WebSocket 重新连接 09:21:29 - 收到 idle timeout(61 秒后) ``` ### 问题分析 1. **录音到停止**:正常(5 秒) 2. **WebSocket 断开**:在 55 秒时断开,说明服务器还是 60 秒超时 3. **重连后发送**:重连成功,但已经超过 60 秒 4. **收到超时**:服务器返回 idle timeout ### 结论 **服务器配置没有生效!** 服务器还在使用 60 秒的超时配置。 ## 🚀 立即操作 ### 1. 确认服务器配置 在服务器上执行: ```bash cat lover/.env | grep VOICE_CALL_IDLE_TIMEOUT ``` 应该显示: ``` VOICE_CALL_IDLE_TIMEOUT=120 ``` ### 2. 重启服务器 ```bash pkill -f "uvicorn.*main:app" cd /path/to/lover uvicorn main:app --host 0.0.0.0 --port 30101 --reload ``` ### 3. 验证服务器启动 服务器启动后,应该看到: ``` INFO: Uvicorn running on http://0.0.0.0:30101 ``` ### 4. 重新测试 1. 进入语音通话页面 2. 按住说话 3-5 秒 3. 松开按钮 4. 观察日志 ### 5. 预期结果 如果服务器配置生效,应该: - ✅ 不会在 60 秒时断开 - ✅ 能够完整发送音频数据 - ✅ 收到 ASR 识别结果 - ✅ 收到 LLM 回复 - ✅ 听到 TTS 语音 ## 🐛 如果还是超时 ### 检查1: 服务器是否真的重启了 ```bash ps aux | grep uvicorn ``` 查看进程的启动时间,应该是最近的时间。 ### 检查2: 配置文件是否正确 ```bash cat lover/.env ``` 确认 `VOICE_CALL_IDLE_TIMEOUT=120` 存在。 ### 检查3: 服务器是否加载了配置 在服务器代码中添加日志: ```python # lover/config.py print(f"VOICE_CALL_IDLE_TIMEOUT = {settings.VOICE_CALL_IDLE_TIMEOUT}") ``` 重启服务器后应该看到: ``` VOICE_CALL_IDLE_TIMEOUT = 120 ``` ## 💡 临时解决方案 如果服务器配置无法立即生效,可以: ### 方案A: 直接修改服务器代码 在 `lover/routers/voice_call.py` 中: ```python async def _idle_watchdog(self): timeout = 120 # 直接硬编码 120 秒 # timeout = settings.VOICE_CALL_IDLE_TIMEOUT or 0 if timeout <= 0: return # ... ``` ### 方案B: 加快客户端发送速度 在 `phone.vue` 中: ```javascript const chunkSize = 3200 const chunkDelay = 50 // 从 100ms 减少到 50ms ``` 这样可以更快地发送完数据。 ## 📞 需要帮助? 如果以上方案都不行,请提供: 1. 服务器 `.env` 文件内容 2. 服务器启动日志 3. 服务器是否真的重启了 4. 客户端完整日志 --- **当前状态**: 代码正常,但服务器配置未生效 **核心问题**: 服务器还在使用 60 秒超时 **解决方案**: 确认服务器配置并重启 **预计时间**: 5 分钟