在开发 ESP32 小智 AI 终端的过程中,开发者经常面临以下挑战:小智服务器与终端之间的协议交互复杂, 消息格式多样(JSON、二进制、JSON-RPC), 握手流程、认证机制、心跳保活等细节不明确, 缺少完整的协议文档和示例。
现在好啦,猫哥分享一款 ESP32小智AI的WebSocket 调试工具,帮你直观的看清整个接入和交互过程。


项目概述
小智 AI 语音助手是一个基于 WebSocket 协议的智能语音交互系统,支持实时语音识别(STT)、语音合成(TTS)和对话功能。在开发和调试过程中,开发者需要一个能够:
- 实时监控 WebSocket 通信
- 发送和接收各种协议消息
- 测试不同的协议场景
- 记录和分析通信日志
目标
本项目的目标是提供一个工程级的 WebSocket 调试工具,具备以下特性:
✅ 完整性 :支持小智协议的所有消息类型
✅ 可视化 :提供直观的图形界面
✅ 实时性 :实时显示通信状态和消息
✅ 可扩展 :易于添加新的协议测试场景
✅ 易用性:开箱即用,无需复杂配置
核心价值
- 开发效率:快速测试和调试协议
- 问题定位:清晰的日志帮助定位问题
- 学习工具:帮助理解小智协议
- 生产辅助:可用于生产环境问题排查
技术原理
WebSocket 通信模型
1. WebSocket 基础
WebSocket 是一种全双工通信协议,建立在 TCP 之上,特点:
- 持久连接:一次握手,多次通信
- 双向通信:客户端和服务器可以随时发送消息
- 低延迟:无需每次请求都建立连接
- 二进制支持:原生支持文本和二进制数据
2. 小智协议特点
小智协议基于 WebSocket,具有以下特点:
消息类型:
- 文本消息(TEXT):JSON 格式的控制消息
- 二进制消息(BINARY):Opus 编码的音频数据
协议流程:
1. 客户端连接 WebSocket
2. 发送 Hello 握手消息(带认证信息)
3. 发送 Listen 开始监听
4. 发送音频数据(二进制)
5. 接收识别结果(JSON)
6. 接收 TTS 音频(二进制)
认证机制:
- 通过 WebSocket Header 传递 Token
- Header 字段:
Authorization: Bearer tokenProtocol-Version: 协议版本Device-Id: 设备标识Client-Id: 客户端标识
代理转发机制
本工具采用中间代理模式,工作原理:
浏览器 ←→ 调试工具后端 ←→ 小智服务器
为什么需要代理?
-
跨域问题(CORS)
- 浏览器直接连接小智服务器可能被 CORS 策略阻止
- 后端作为中间层可以绕过 CORS 限制
-
协议转换
- 浏览器 WebSocket API 与小智协议可能不完全兼容
- 后端可以处理协议细节
-
日志记录
- 代理可以记录所有通信
- 提供完整的抓包日志
-
消息增强
- 添加时间戳
- 格式化 JSON
- 分类显示
转发流程
客户端 → 小智服务器:
1. 浏览器发送消息到调试工具
2. 调试工具记录日志
3. 调试工具转发到小智服务器
小智服务器 → 客户端:
1. 小智服务器发送消息到调试工具
2. 调试工具记录日志
3. 调试工具转发到浏览器
消息编码与解码
1. JSON 消息
发送:
javascript
// 前端
const message = {
action: "send",
message_type: "text",
payload: JSON.stringify({
"type": "hello",
"device_id": "web-debugger"
})
};
ws.send(JSON.stringify(message));
接收:
python
# 后端
data = await client_ws.receive_json()
if data["action"] == "send":
await server_ws.send(data["payload"])
2. 二进制消息(Opus)
发送:
javascript
// 前端
const audioData = await file.arrayBuffer();
const base64Data = btoa(String.fromCharCode(...new Uint8Array(audioData)));
const message = {
action: "send",
message_type: "binary",
payload: base64Data
};
ws.send(JSON.stringify(message));
解码:
python
# 后端
binary_data = base64.b64decode(data["payload"])
await server_ws.send(binary_data)
接收:
python
# 后端
async for message in server_ws:
if isinstance(message, bytes):
# 二进制消息
base64_data = base64.b64encode(message).decode()
await client_ws.send_json({
"type": "message",
"direction": "recv",
"opcode": "binary",
"length": len(message),
"payload": base64_data
})
系统架构
整体架构图
┌─────────────────────────────────────────────────────────────┐
│ 浏览器(前端) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ index.html │ │ app.js │ │style.css │ │
│ └──────────────┘ └──────────────┘ └──────────┘ │
└────────────────────────┬────────────────────────────────────┘
│ WebSocket
│ ws://localhost:8000/debug
▼
┌─────────────────────────────────────────────────────────────┐
│ 调试工具后端(FastAPI) │
│ ┌──────────────────────────────────────────────┐ │
│ │ @app.websocket("/debug") │ │
│ │ - 接收客户端消息 │ │
│ │ - 记录日志 │ │
│ │ - 转发到小智服务器 │ │
│ │ - 接收小智服务器消息 │ │
│ │ - 记录日志 │ │
│ │ - 转发到客户端 │ │
│ └──────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────┐ │
│ │ PacketLogger │ │
│ │ - 日志存储 │ │
│ │ - 日志查询 │ │
│ └──────────────────────────────────────────────┘ │
└────────────────────────┬────────────────────────────────────┘
│ WebSocket
│ ws://xiaozhi-server:8001/ws
▼
┌─────────────────────────────────────────────────────────────┐
│ 小智服务器 │
│ - Hello 握手 │
│ - Listen 监听 │
│ - STT 语音识别 │
│ - TTS 语音合成 │
│ - 对话管理 │
└─────────────────────────────────────────────────────────────┘
后端架构
1. FastAPI 应用
核心组件:
python
app = FastAPI(title="Xiaozhi WebSocket Debugger")
# 中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 静态文件托管
app.mount("/static", StaticFiles(directory=frontend_path), name="static")
# HTTP 路由
@app.get("/") # 主页
@app.get("/debug-info") # 调试信息
@app.get("/test-*.html") # 测试页面
# WebSocket 路由
@app.websocket("/debug") # 主调试端点
@app.websocket("/test") # 简单测试端点
2. WebSocket 处理流程
python
@app.websocket("/debug")
async def debug_ws(client_ws: WebSocket):
# 1. 接受连接
await client_ws.accept()
# 2. 初始化会话
session_id = str(uuid.uuid4())[:8]
config = None
server_ws = None
# 3. 消息循环
while True:
# 接收客户端消息
data = await client_ws.receive_json()
# 处理不同类型的消息
if data["action"] == "connect":
# 连接小智服务器
server_ws = await connect_to_server(config)
elif data["action"] == "send":
# 转发消息到小智服务器
await server_ws.send(message)
elif data["action"] == "get_logs":
# 返回日志
logs = logger.get_recent(limit)
await client_ws.send_json({"type": "logs", "logs": logs})
3. 消息转发任务
python
async def forward_server_to_client(client_ws, server_ws, session_id):
"""
从小智服务器转发消息到客户端
"""
try:
async for message in server_ws:
if isinstance(message, bytes):
# 二进制消息(音频)
packet = logger.log("recv", "binary", length=len(message))
await client_ws.send_json({
"type": "message",
"direction": "recv",
"opcode": "binary",
"length": len(message),
"payload": base64.b64encode(message).decode()
})
else:
# 文本消息(JSON)
packet = logger.log("recv", "text", payload=message)
await client_ws.send_json({
"type": "message",
"direction": "recv",
"opcode": "text",
"payload": message
})
except Exception as e:
# 错误处理
packet = logger.log("system", "error", payload=str(e))
await client_ws.send_json({"type": "log", "packet": packet})
4. 日志记录器
python
class PacketLogger:
def __init__(self):
self.packets = []
self.max_packets = 1000
def log(self, direction: str, opcode: str,
payload: Optional[str] = None,
length: Optional[int] = None):
"""
记录一个数据包
参数:
direction: 方向(send/recv/system/error)
opcode: 操作码(text/binary/connect/error)
payload: 载荷内容
length: 二进制数据长度
"""
packet = {
"timestamp": datetime.now().strftime("%H:%M:%S.%f")[:-3],
"direction": direction,
"opcode": opcode,
"payload": payload,
"length": length
}
self.packets.append(packet)
# 限制日志数量
if len(self.packets) > self.max_packets:
self.packets.pop(0)
return packet
def get_recent(self, limit: int = 100):
"""获取最近的日志"""
return self.packets[-limit:]
前端架构
1. 组件结构
index.html
├── 头部(Header)
│ ├── 标题
│ └── 状态指示器
├── 侧边栏(Sidebar)
│ ├── 连接配置
│ ├── 发送消息
│ ├── 音频发送
│ └── 快速模板
└── 主内容(Main Content)
└── 抓包日志
2. JavaScript 模块
核心模块:
javascript
// 1. 连接管理
let ws = null;
let isConnected = false;
function connect() {
ws = new WebSocket('ws://localhost:8000/debug');
ws.onopen = handleOpen;
ws.onmessage = handleMessage;
ws.onerror = handleError;
ws.onclose = handleClose;
}
// 2. 状态管理
function updateConnectionStatus(connected) {
isConnected = connected;
// 更新 UI
}
// 3. 消息发送
function sendMessage(messageType, payload) {
const message = {
action: "send",
message_type: messageType,
payload: payload
};
ws.send(JSON.stringify(message));
}
// 4. 日志管理
let logs = [];
function addLogEntry(packet) {
logs.push(packet);
renderLogs();
}
function renderLogs() {
// 渲染日志到 UI
}
// 5. 过滤器
let currentFilter = 'all';
function filterLogs(filter) {
currentFilter = filter;
renderLogs();
}
3. WebSocket 消息处理
javascript
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch (data.type) {
case 'log':
// 系统日志
addLogEntry(data.packet);
// 更新连接状态
if (data.packet.opcode === 'connected') {
updateConnectionStatus(true);
} else if (data.packet.opcode === 'error') {
updateConnectionStatus(false);
}
break;
case 'message':
// 收到消息(从小智服务器)
addLogEntry({
timestamp: getCurrentTimestamp(),
direction: data.direction,
opcode: data.opcode,
payload: data.payload,
length: data.length
});
break;
case 'logs':
// 日志列表
logs = data.logs;
renderLogs();
break;
case 'error':
// 错误消息
updateConnectionStatus(false);
alert('连接错误: ' + data.message);
break;
}
};
4. UI 更新机制
实时更新:
javascript
function renderLogs() {
const container = document.getElementById('logContainer');
container.innerHTML = '';
logs.forEach(log => {
// 根据过滤器显示
if (currentFilter !== 'all' &&
getOpcodeClass(log.opcode) !== currentFilter) {
return;
}
// 创建日志条目
const entry = createLogEntry(log);
container.appendChild(entry);
});
// 自动滚动到底部
container.scrollTop = container.scrollHeight;
}
核心功能
1. WebSocket 连接管理
功能描述
提供完整的 WebSocket 连接生命周期管理,包括:
- 连接建立:建立到调试工具的连接
- 认证配置:支持 Token、Device ID 等认证信息
- 状态监控:实时显示连接状态
- 断线重连:支持手动重连
实现细节
连接流程:
javascript
function connect() {
// 1. 创建 WebSocket
ws = new WebSocket('ws://localhost:8000/debug');
// 2. 设置事件处理器
ws.onopen = () => {
console.log('已连接到后端服务');
// 3. 发送连接配置
ws.send(JSON.stringify({
action: 'connect',
config: {
server_url: serverUrl,
token: token,
device_id: deviceId,
protocol_version: parseInt(protocolVersion)
}
}));
};
ws.onmessage = handleMessage;
ws.onerror = handleError;
ws.onclose = handleClose;
}
后端处理:
python
@app.websocket("/debug")
async def debug_ws(client_ws: WebSocket):
await client_ws.accept()
while True:
data = await client_ws.receive_json()
if data["action"] == "connect":
config = data["config"]
# 构建认证头
headers = {
"Authorization": f"Bearer {config.get('token', '')}",
"Protocol-Version": str(config.get('protocol_version', 1)),
"Device-Id": config.get('device_id', 'web-debugger'),
"Client-Id": config.get('client_id', f'debug-{session_id}')
}
# 连接目标服务器
server_ws = await websockets.connect(
config["server_url"],
extra_headers=headers,
max_size=None,
ping_interval=None,
close_timeout=10
)
使用场景
- 开发测试:快速测试连接配置
- 协议调试:验证握手流程
- 问题排查:检查连接失败原因
2. 消息收发
功能描述
支持发送和接收两种类型的消息:
- 文本消息(TEXT):JSON 格式的控制消息
- 二进制消息(BINARY):Opus 编码的音频数据
实现细节
发送文本消息:
javascript
function sendTextMessage() {
const payload = document.getElementById('messagePayload').value;
ws.send(JSON.stringify({
action: 'send',
message_type: 'text',
payload: payload
}));
// 添加到日志
addLogEntry({
timestamp: getCurrentTimestamp(),
direction: 'send',
opcode: 'text',
payload: payload
});
}
发送二进制消息:
javascript
function sendBinaryMessage() {
const base64Data = document.getElementById('binaryPayload').value;
ws.send(JSON.stringify({
action: 'send',
message_type: 'binary',
payload: base64Data
}));
// 添加到日志
addLogEntry({
timestamp: getCurrentTimestamp(),
direction: 'send',
opcode: 'binary',
length: base64Data.length
});
}
后端转发:
python
elif data["action"] == "send":
if not server_ws:
await client_ws.send_json({
"type": "error",
"message": "Not connected"
})
continue
if data["message_type"] == "text":
await server_ws.send(data["payload"])
packet = logger.log("send", "text", payload=data["payload"])
await client_ws.send_json({"type": "log", "packet": packet})
elif data["message_type"] == "binary":
binary_data = base64.b64decode(data["payload"])
await server_ws.send(binary_data)
packet = logger.log("send", "binary", length=len(binary_data))
await client_ws.send_json({"type": "log", "packet": packet})
使用场景
- 协议测试:发送各种 JSON 消息
- 音频发送:发送 Opus 音频数据
- 命令执行:发送控制命令
3. 协议测试模板
功能描述
提供预定义的协议消息模板,快速测试常见场景:
- Hello 握手:设备握手协议
- Listen 监听:开始监听语音
- JSON-RPC 调用:方法调用
- 唤醒词:发送唤醒词
实现细节
模板定义:
javascript
const templates = {
hello: {
type: "hello",
device_id: "web-debugger",
protocol_version: 1,
capabilities: ["stt", "tts", "dialog"]
},
listen: {
type: "listen",
enable: true,
format: "opus",
sample_rate: 16000
},
jsonrpc: {
jsonrpc: "2.0",
method: "dialog.send",
params: {
text: "你好,小智"
},
id: 1
},
wakeup: {
type: "wakeup",
word: "小智小智"
}
};
function applyTemplate(templateName) {
const template = templates[templateName];
document.getElementById('messagePayload').value = JSON.stringify(template, null, 2);
}
使用场景
- 快速测试:一键发送常用协议
- 协议学习:了解协议格式
- 场景模拟:模拟真实使用场景
4. 音频功能
功能描述
支持发送音频文件到小智服务器:
- 文件格式:.opus, .wav, .mp3
- 自动转换:自动读取并转换为二进制
- 大小显示:显示文件大小信息
实现细节
文件读取:
javascript
async function sendAudioFile() {
const fileInput = document.getElementById('audioFile');
const file = fileInput.files[0];
if (!file) {
alert('请选择音频文件');
return;
}
// 读取文件
const arrayBuffer = await file.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
// 转换为 Base64
const base64Data = btoa(String.fromCharCode(...uint8Array));
// 发送
ws.send(JSON.stringify({
action: 'send',
message_type: 'binary',
payload: base64Data
}));
// 添加到日志
addLogEntry({
timestamp: getCurrentTimestamp(),
direction: 'send',
opcode: 'binary',
length: arrayBuffer.byteLength,
filename: file.name
});
}
使用场景
- 语音测试:发送测试音频
- TTS 测试:测试语音合成
- STT 测试:测试语音识别
5. 抓包日志
功能描述
类似 Wireshark 的日志展示功能:
- 时间戳:精确到毫秒
- 方向标识:发送/接收/系统/错误
- 操作码:TEXT/BINARY/CONNECT 等
- JSON 格式化:自动格式化 JSON
- 日志过滤:按类型过滤
- 日志导出:导出为 JSON 文件
实现细节
日志数据结构:
javascript
{
timestamp: "12:34:56.789", // 时间戳
direction: "send", // 方向:send/recv/system/error
opcode: "text", // 操作码:text/binary/connect/error
payload: "{...}", // 载荷内容
length: 123 // 二进制数据长度
}
日志渲染:
javascript
function renderLogs() {
const container = document.getElementById('logContainer');
container.innerHTML = '';
logs.forEach(log => {
// 过滤
if (currentFilter !== 'all' &&
getOpcodeClass(log.opcode) !== currentFilter) {
return;
}
// 创建条目
const entry = document.createElement('div');
entry.className = `log-entry ${getDirectionClass(log.direction)} ${getOpcodeClass(log.opcode)}`;
// 时间戳
const timestamp = document.createElement('span');
timestamp.className = 'log-timestamp';
timestamp.textContent = log.timestamp;
// 方向
const direction = document.createElement('span');
direction.className = 'log-direction';
direction.textContent = getDirectionLabel(log.direction);
// 操作码
const opcode = document.createElement('span');
opcode.className = 'log-opcode';
opcode.textContent = log.opcode;
// 载荷
const payload = document.createElement('pre');
payload.className = 'log-payload';
if (log.opcode === 'text') {
// 格式化 JSON
try {
const json = JSON.parse(log.payload);
payload.textContent = JSON.stringify(json, null, 2);
} catch {
payload.textContent = log.payload;
}
} else if (log.opcode === 'binary') {
// 显示二进制信息
payload.textContent = `[Binary Data] Length: ${log.length} bytes`;
} else {
payload.textContent = log.payload;
}
entry.appendChild(timestamp);
entry.appendChild(direction);
entry.appendChild(opcode);
entry.appendChild(payload);
container.appendChild(entry);
});
// 滚动到底部
container.scrollTop = container.scrollHeight;
}
日志导出:
javascript
function exportLogs() {
const dataStr = JSON.stringify(logs, null, 2);
const blob = new Blob([dataStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `websocket-logs-${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
}
使用场景
- 问题排查:查看完整的通信日志
- 协议分析:分析协议交互
- 性能分析:查看消息时序
- 报告生成:导出日志用于报告
实现细节
1. 跨域问题解决
问题
浏览器直接连接小智服务器可能遇到 CORS 错误:
Access to WebSocket at 'ws://xiaozhi-server:8001/ws'
from origin 'http://localhost:8000' has been blocked by CORS policy
解决方案
方案 1:后端代理(采用)
通过 FastAPI 后端作为代理,绕过 CORS 限制:
python
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
方案 2:静态文件托管
将前端页面托管在 FastAPI 上,避免跨域:
python
app.mount("/static", StaticFiles(directory=frontend_path), name="static")
@app.get("/")
async def root():
return FileResponse(os.path.join(frontend_path, "index.html"))
2. 超时处理
问题
连接目标服务器时可能长时间无响应。
解决方案
使用 asyncio.wait_for 设置超时:
python
try:
server_ws = await asyncio.wait_for(
websockets.connect(
config["server_url"],
extra_headers=headers,
max_size=None,
ping_interval=None,
close_timeout=10
),
timeout=10.0 # 10秒超时
)
packet = logger.log("system", "connected", payload="WebSocket connected")
await client_ws.send_json({"type": "log", "packet": packet})
except asyncio.TimeoutError:
packet = logger.log("system", "error",
payload="Connection timeout: Target server did not respond within 10 seconds")
await client_ws.send_json({"type": "log", "packet": packet})
except Exception as e:
packet = logger.log("system", "error", payload=f"Connection failed: {str(e)}")
await client_ws.send_json({"type": "log", "packet": packet})
3. 消息接收优化
问题
FastAPI 的 receive() 方法在某些情况下无法正确接收消息。
解决方案
使用 receive_json() 方法直接获取 JSON 对象:
python
# 之前(可能有问题)
msg = await client_ws.receive()
if msg["type"] == "text":
data = json.loads(msg["text"])
# 现在(更可靠)
data = await client_ws.receive_json()
4. 连接状态同步
问题
前端连接状态与实际状态不同步。
解决方案
后端在连接成功/失败时发送状态消息:
python
# 连接成功
packet = logger.log("system", "connected", payload="WebSocket connected")
await client_ws.send_json({"type": "log", "packet": packet})
# 连接失败
packet = logger.log("system", "error", payload=f"Connection failed: {str(e)}")
await client_ws.send_json({"type": "log", "packet": packet})
前端根据收到的消息更新状态:
javascript
if (data.type === 'log') {
addLogEntry(data.packet);
if (data.packet.opcode === 'connected') {
updateConnectionStatus(true);
} else if (data.packet.opcode === 'error') {
updateConnectionStatus(false);
}
}
5. 批处理文件编码
问题
Windows 批处理文件使用 UTF-8 编码时,中文显示为乱码。
解决方案
在批处理文件开头设置代码页:
batch
@echo off
chcp 65001 >nul
echo Xiaozhi WebSocket Debugger
或使用英文提示避免编码问题。
技术栈
后端技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Python | 3.8+ | 主要开发语言 |
| FastAPI | Latest | Web 框架 |
| WebSockets | Latest | WebSocket 支持 |
| Uvicorn | Latest | ASGI 服务器 |
| asyncio | 内置 | 异步编程 |
前端技术栈
| 技术 | 用途 |
|---|---|
| HTML5 | 页面结构 |
| CSS3 | 样式和布局 |
| JavaScript (ES6+) | 交互逻辑 |
| WebSocket API | WebSocket 通信 |
| FileReader API | 文件读取 |
协议栈
| 协议 | 用途 |
|---|---|
| WebSocket | 底层通信协议 |
| JSON | 文本消息格式 |
| Base64 | 二进制数据编码 |
| Opus | 音频编码格式 |
| JSON-RPC 2.0 | 远程过程调用 |
使用场景
1. 开发调试
场景:开发小智集成应用时需要测试协议。
使用方法:
- 启动调试工具
- 配置连接参数
- 发送测试消息
- 查看返回结果
- 分析日志
价值:
- 快速验证协议实现
- 定位通信问题
- 理解协议细节
2. 协议学习
场景:学习小智协议的交互流程。
使用方法:
- 使用快速模板发送消息
- 观察返回消息
- 分析日志时序
- 理解协议规则
价值:
- 直观展示协议流程
- 帮助理解协议
- 提供参考实现
3. 问题排查
场景:生产环境出现通信问题。
使用方法:
- 配置生产服务器地址
- 复现问题场景
- 查看详细日志
- 分析错误原因
- 导出日志报告
价值:
- 完整的通信日志
- 清晰的错误信息
- 便于问题定位
4. 性能测试
场景:测试服务器的性能和稳定性。
使用方法:
- 发送大量消息
- 观察响应时间
- 检查连接稳定性
- 分析日志统计
价值:
- 评估服务器性能
- 发现性能瓶颈
- 优化通信策略
最佳实践
1. 连接配置
推荐配置:
javascript
{
server_url: "ws://xiaozhi-server:8001/ws",
token: "your-bearer-token",
device_id: "web-debugger",
protocol_version: 1
}
注意事项:
- 确保服务器地址正确
- Token 必须有效
- Device ID 唯一标识设备
2. 消息发送
最佳实践:
- JSON 消息使用格式化输出
- 二进制消息先测试小数据
- 音频文件大小适中(<10MB)
- 使用快速模板提高效率
3. 日志管理
建议:
- 定期导出重要日志
- 使用过滤器快速定位
- 关注错误和警告消息
- 分析消息时序关系
4. 故障排查
排查步骤:
- 检查连接状态
- 查看错误日志
- 验证配置参数
- 测试网络连接
- 联系技术支持
5. 安全建议
安全措施:
- 不要在生产环境暴露调试工具
- 使用 HTTPS/WSS 加密通信
- 保护 Token 不泄露
- 定期更新依赖包
总结
小智 WebSocket 调试工具是一个功能完善、设计精良的工程级调试工具,具有以下特点:
核心优势
✅ 完整性 :覆盖小智协议的所有功能
✅ 可靠性 :完善的错误处理和超时机制
✅ 易用性 :直观的界面和快速模板
✅ 可扩展性 :易于添加新功能
✅ 专业性:类似 Wireshark 的日志展示
技术亮点
- 代理架构:解决 CORS 和协议兼容问题
- 异步处理:高性能的消息转发
- 实时更新:即时的状态和日志反馈
- 模块化设计:清晰的代码结构
- 完整文档:详细的使用说明
适用场景
- 开发调试
- 协议学习
- 问题排查
- 性能测试
- 教学演示
未来展望
- 支持更多协议格式
- 添加消息录制和回放
- 提供统计分析功能
- 支持多会话管理
- 集成自动化测试
总结
ESP32 小智 AI 终端的开发调试一直是一个复杂且具有挑战性的任务。协议交互不清晰、缺少可视化工具、测试场景受限等问题严重影响了开发效率。
本工具通过提供完整的协议交互可视化平台,解决了这些痛点,为开发者提供了:
- 直观的协议交互展示
- 完整的协议支持
- 灵活的测试工具
- 强大的日志记录
这些功能显著提升了开发效率,降低了开发门槛,增强了问题排查能力,是 ESP32 小智 AI 终端开发不可或缺的利器!