# 03 · 使用注意事项

## 对话流程

### 连接建立

```
解析配置 → 初始化日志/音频设备
  → POST token_url（HMAC 签名）获取 Token
  → WSS 握手
  → 发送 voiceChat/update 对话链路配置更新事件
  → 上行通道就绪，进入对话
```

### 上行（语音采集 → 云端）

```
MIC(ALSA) → 重采样(48kHz→16kHz) → Opus 编码 → WS 二进制帧 → 云端
```

### 下行（云端 → 播放）

```
WS 二进制 Opus 帧 → Opus 解码 → 重采样(16kHz→48kHz) → ALSA 播放
WS 文本 JSON 事件 → ASR / TTS 文本 / 打断 / 有声书
```

### 心跳与重连

| 机制 | 默认参数 | 行为 |
| --- | --- | --- |
| 应用心跳 | 30 s | lws 服务线程发送 PING |
| 传输超时 | 300 s 无数据 | 判定断链，cleanup + 重连 |
| 会话空闲 | 600 s | 主动关闭 WSS |
| 重连退避 | 3 s → 30 s，最多 10 次 | 指数退避 + 随机抖动 |

### 打断

收到 `EVENT/CALL_AGENT_INTERRUPTED` 后：立即清空播放缓冲，上行不中断。

### 有声书

收到 `AUDIO_BOOK_PLAY` 携带 MP3 URL → HTTP/HTTPS 流式拉取 → minimp3 解码 → speexdsp 重采样 → 喇叭播放。支持 PING/PANG 心跳保活与 PONG 超时停播。

## A. 凭据与安全

### 必须配置凭据

`bot_id`、`access_key_id`、`access_key_secret` 为必填项。程序启动时未找到有效凭据会立即报错退出。

### 鉴权前置条件

1. **系统时钟准确**：Token 签名含毫秒时间戳，时钟偏差大会导致 `INVALID_SIGNATURE` 错误。目标板务必配置 NTP。
2. **公网 443 可达**：`api.joyinside.com`（Token 服务）、`ws.joyinside.com`（WSS）及有声书 CDN。
3. **AK/SK 与 botId 匹配**：错配会导致签名失败。

## B. 音频设备配置

### ALSA 设备名

- `--mic_device`：麦克风采集设备（默认 `main_mic1`），需根据实际硬件修改
- 可通过 `arecord -l` 查看可用采集设备
- 可通过 `aplay -l` 查看可用播放设备

### 采样率配置

本项目采用**软件重采样**方案：

```
硬件采样率（hw_sample_rate，默认 48000）  ←→  管线采样率（sample_rate，默认 16000）
```

- `--hw_sample_rate` / `--hw_channels`：ALSA 硬件实际打开的参数
- `--sample_rate` / `--channels`：Opus 编解码和 WS 传输使用的参数
- speexdsp 负责两者之间的重采样

**注意**：修改 `sample_rate` 后需同步确认 Opus 编解码器支持（建议保持 16000）。

### 通道混音

- `--mix_channel_a` / `--mix_channel_b`：从多声道硬件输入中选取通道进行混音
- `--mix_channel_b=none`：单通道模式，仅使用 channel_a

### 增益调节

- `--capture_gain`：麦克风软件增益，范围 [0, 16]，默认 1.0
- `--playback_gain`：播放软件增益，范围 [0, 16]，默认 1.0
- 过大的增益可能导致削波失真

## C. 网络

### 重连机制

- WS 断线后指数退避重连：3 s → 6 s → 12 s → ... → 30 s（最大），最多 10 次
- 连接稳定 5 秒后重试计数归零
- 重连期间"无响应"属正常，日志中可见重连调度信息

### 超时设置

- `EventLoopConfig::transport_idle_timeout_ms`（300 s）：传输层无数据判定断链
- `EventLoopConfig::session_idle_timeout_ms`（600 s）：会话空闲主动关闭
- `JoyInsideWSConfig::heartbeat_interval_ms`（30 s）：应用层 PING 间隔

### DNS 与 TLS 优化

- 默认启用 DNS 缓存（`dns_cache_enabled=true`）
- 默认启用 TCP Fast Open（`tcp_fastopen_connect=true`）
- libcurl share handle 复用 DNS/TLS session，降低重连开销

## D. 代码修改指南

### 修改音频编码参数

编码参数通过 `voiceChat/update` 与服务端协商，修改 `JoyInsideChatConfigReq` 中的字段：

```cpp
// joyinside_ws_client.h 中的默认值
input_codec = "opus"
input_samplerate = "16000"
output_codec = "opus"
output_samplerate = "16000"
output_frame_size_ms = "60"
```

### 添加自定义事件处理

在 `application.cpp` 的 `parse_server_message()` 中扩展 JSON 事件分发逻辑。

### 修改重连策略

编辑 `EventLoopConfig` 中的参数：

```cpp
reconnect_max_retries = 10;      // 最大重连次数
reconnect_base_delay_ms = 3000;  // 初始退避
reconnect_max_delay_ms = 30000;  // 最大退避
```

### 有声书相关修改

- `AudiobookDownloader`：HTTP 下载策略、缓冲大小
- `AudiobookMp3Decoder`：解码线程优先级、输出队列容量
- `AudiobookSession`：状态机流转、PING/PANG 超时

## E. 调试

### 日志级别

```bash
--log_level=trace   # 最详细，包括每帧音频处理
--log_level=debug   # 调试信息
--log_level=info    # 默认，关键事件
--log_level=warn    # 警告
--log_level=err     # 仅错误
--log_level=off     # 关闭
```

### PCM 导出

```bash
# 从上行建立后开始录制，最多 60 秒
--dump_mic_pcm=true --dump_mic_pcm_seconds=60

# 从采集开始即导出
--dump_mic_pcm=true --dump_mic_pcm_from_start=true

# 指定输出路径
--dump_mic_pcm=true --dump_mic_pcm_path=/tmp/mic_debug.wav
```

### 稳定性统计

```bash
--stats_enable=true --stats_interval_sec=10
```

每 10 秒打印一次内存使用和各线程 CPU 占用，用于压测和内存泄漏排查。

## F. 故障速查

| 现象 | 优先排查 |
| --- | --- |
| `missing bot_id, access_key_id, or access_key_secret` | 凭据未配置 |
| Token 失败 / `INVALID_SIGNATURE` | 系统时钟是否同步（NTP）；AK/SK/botId 是否匹配 |
| WSS 握手失败 | DNS 解析、`ws.joyinside.com:443` 防火墙 |
| 无声音输出 | ALSA 设备参数是否正确；`aplay -l` 检查声卡 |
| 采集无数据 | `--mic_device` 是否正确；`arecord` 能否录音 |
| TTS 卡顿 | 网络带宽/延迟；检查日志中是否有重连 |
| 有声书无声 | CDN 是否可达（443 端口） |
| 程序立即退出 | 检查 `--help` 查看参数要求 |
| 重连循环 | 检查网络连通性；是否超过最大重试次数 |

## G. 编译注意事项

- 交叉编译时 sysroot 中各库版本须与目标板一致，避免 ABI 不兼容
- `thirdparty/` 中的库不要单独升级，需验证与项目整体兼容性
- 若 Ninja 可用，`cross-build.sh` 会自动使用 Ninja 作为后端（更快）
- 若 ccache 可用，自动启用编译缓存