
# MQTT 接入（原生协议）

*低带宽 / IoT 设备用 MQTT 接入。连接由 mqtt-gateway 鉴权（客户端 Token 或设备接入密码），进入与 WSS 相同的房间模型*

设备直接连 `mqtt-gateway`（内嵌 broker），本部署地址：**`124.174.6.145:2883`**。连接在 CONNECT 时鉴权，然后用 `hearo/...` 系列 topic 发布音频、订阅下行。本页是 Hearo 原生 MQTT 协议；房间由 topic 路径里的 `{room}` 指定。

> 💡 **先读这个**：所有终端（设备/App/网页）的统一接入模型、API Key、客户端 Token 的签发与房间分配，集中在 [客户端与接入模型](/docs/clients)。本页只讲 MQTT 这一种传输的具体 topic 与帧格式。

## ① 连接（CONNECT 鉴权）

> ℹ️ **本部署的 MQTT 地址**：`124.174.6.145:2883`（由平台管理员在 运营中心 → 平台设置 → 接入地址 配置）。

| 字段 | 说明 |
|---|---|
| 地址 | `124.174.6.145`，端口 `2883`（TCP） |
| password | 二选一：**客户端 Token**（JWT，后端用 API Key 签发）或**设备接入密码**（`hkd_` 开头的短密码，在控制台 → 设备 页生成/复制，适合密码字段有长度限制的固件） |
| username | 用客户端 Token 时：留空或填 clientId（必须与 Token 的 `sub` 或 MQTT Client ID 一致）；用设备接入密码时：任意（建议填 deviceId） |
| QoS | 音频 0（实时优先）、控制 1；下行统一 QoS 0 |

broker 在 CONNECT 时校验（Token 验签名 + 有效期；短密码查平台登记）。两种凭据都对应到一个工作空间——**工作空间由鉴权决定，不在 topic 里**。无有效凭据的连接被拒绝。

> ⚠️ **传输加密**：broker 本身监听明文 TCP；生产环境建议在部署侧加一层 TLS 终结（L4 代理）提供 mqtts，或至少使用可随时重置的**设备接入密码**（泄露后在设备页一键重置即失效），不要把长期 Token 走明文网络。

## ② Topic

| Topic | 类型 | 路径 |
|---|---|---|
| up/control | JSON | `hearo/{ns}/{room}/{deviceId}/up/control` |
| up/audio | binary | `hearo/{ns}/{room}/{deviceId}/up/audio` |
| down/audio | binary | `hearo/{ns}/{room}/{deviceId}/down/audio` |
| down/control | JSON | `hearo/{ns}/{room}/{deviceId}/down/control` |

`{ns}` 是你自定的命名空间段（如产品线名），下行会原样回显在同一路径下；`{room}` 是房间名（工作空间内唯一，见 [房间与分组](/docs/rooms)）；`{deviceId}` 是设备标识。**注意：工作空间不在 topic 里**——它来自 CONNECT 鉴权，房间会自动限定在你的工作空间内（同名房间跨空间互不相通）。

## ③ 加入房间（join 帧）

连上后往 `up/control` 发一条 join（QoS 1），网关据此把你拨入 topic 里的房间：

```json
// topic: hearo/{ns}/{room}/{deviceId}/up/control
{ "type": "join", "name": "门口设备", "encoding": "opus" }
// encoding: "pcm"(默认, s16le/16k/mono，别名 pcm_s16le/pcm16/l16) | "opus"(16k 单声道)
```

`up/control` 上的其他消息：`{"type":"leave"}` 离开房间；除 join/leave 以外的任何 JSON（如 `interrupt`、`speech_start`）会**原样转发进房间**，语义与 [WebSocket 控制消息](/docs/websocket) 一致。

## ④ 上行音频

持续把音频帧发布到 `up/audio`（二进制，QoS 0）。`pcm` 为 20ms/640B 的 s16le 帧；`opus` 为 16k 单声道 Opus 包。网关解码为统一 16k PCM 再进房。

## ⑤ 下行

订阅 `down/audio` 收房间混音（按 join 的 `encoding` 编码；opus 为 20ms 帧），订阅 `down/control` 收转写 / 字幕 / roster 等 JSON 事件（与 [WebSocket 事件](/docs/websocket) 相同）。

## 退出 / 断线

发 `{"type":"leave"}` 主动离开；MQTT 连接断开时网关**自动**清理会话并把设备标记离线，无需配置遗嘱消息（LWT）。在线状态（presence）见 [客户端与接入模型](/docs/clients)。

> ℹ️ **原生协议 vs 统一模型**：原生协议的房间由 topic 路径指定。若希望房间由平台的 `client→room` 映射决定、可后台实时切房，用 [aispea 设备接入](/docs/aispea-mqtt)（MQTT）或默认的 [WebSocket](/docs/websocket)；浏览器也可评估 WebRTC（实验）。
