Документация смешанного протокола связи MQTT + UDP

Документация смешанного протокола связи MQTT + UDP

Документация смешанного протокола связи MQTT + UDP, организованная на основе реализации кода, описывающая способ взаимодействия между устройством и сервером через MQTT для передачи управляющих сообщений и через UDP для передачи аудиоданных.

1. Обзор протокола

Этот протокол использует смешанный способ передачи:

  • MQTT: Для управляющих сообщений, синхронизации состояний, обмена JSON данными
  • UDP: Для передачи аудиоданных в реальном времени, поддержка шифрования

1.1 Особенности протокола

  • Двухканальный дизайн: Разделение управления и данных, обеспечение реального времени
  • Зашифрованная передача: UDP аудиоданные используют шифрование AES-CTR
  • Защита порядковыми номерами: Предотвращение повтора и нарушения порядка пакетов данных
  • Автоматическое переподключение: Автоматическое переподключение при разрыве MQTT соединения

2. Обзор общего потока

  sequenceDiagram
    participant Device as ESP32 устройство
    participant MQTT as MQTT сервер
    participant UDP as UDP сервер

    Note over Device, UDP: 1. Установка MQTT соединения
    Device->>MQTT: MQTT Connect
    MQTT->>Device: Connected

    Note over Device, UDP: 2. Запрос аудиоканала
    Device->>MQTT: Hello Message (type: "hello", transport: "udp")
    MQTT->>Device: Hello Response (Информация о UDP соединении + ключ шифрования)

    Note over Device, UDP: 3. Установка UDP соединения
    Device->>UDP: UDP Connect
    UDP->>Device: Connected

    Note over Device, UDP: 4. Передача аудиоданных
    loop Передача аудиопотока
        Device->>UDP: Зашифрованные аудиоданные (Opus)
        UDP->>Device: Зашифрованные аудиоданные (Opus)
    end

    Note over Device, UDP: 5. Обмен управляющими сообщениями
    par Управляющие сообщения
        Device->>MQTT: Listen/TTS/MCP сообщения
        MQTT->>Device: STT/TTS/MCP ответы
    end

    Note over Device, UDP: 6. Закрытие соединения
    Device->>MQTT: Goodbye Message
    Device->>UDP: Disconnect

3. MQTT канал управления

3.1 Установка соединения

Устройство подключается к серверу через MQTT, параметры соединения включают:

  • Endpoint: Адрес и порт MQTT сервера
  • Client ID: Уникальный идентификатор устройства
  • Username/Password: Учетные данные аутентификации
  • Keep Alive: Интервал heartbeat (по умолчанию 240 секунд)

3.2 Обмен Hello сообщениями

3.2.1 Отправка Hello устройством

{
  "type": "hello",
  "version": 3,
  "transport": "udp",
  "features": {
    "mcp": true
  },
  "audio_params": {
    "format": "opus",
    "sample_rate": 16000,
    "channels": 1,
    "frame_duration": 60
  }
}

3.2.2 Ответ Hello сервера

{
  "type": "hello",
  "transport": "udp",
  "session_id": "xxx",
  "audio_params": {
    "format": "opus",
    "sample_rate": 24000,
    "channels": 1,
    "frame_duration": 60
  },
  "udp": {
    "server": "192.168.1.100",
    "port": 8888,
    "key": "0123456789ABCDEF0123456789ABCDEF",
    "nonce": "0123456789ABCDEF0123456789ABCDEF"
  }
}

Описание полей:

  • udp.server: Адрес UDP сервера
  • udp.port: Порт UDP сервера
  • udp.key: Ключ шифрования AES (шестнадцатеричная строка)
  • udp.nonce: Nonce шифрования AES (шестнадцатеричная строка)

3.3 Типы JSON сообщений

3.3.1 Устройство→Сервер

Listen сообщение

{
  "session_id": "xxx",
  "type": "listen",
  "state": "start",
  "mode": "manual"
}

Abort сообщение

{
  "session_id": "xxx",
  "type": "abort",
  "reason": "wake_word_detected"
}

MCP сообщение

{
  "session_id": "xxx",
  "type": "mcp",
  "payload": {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {...}
  }
}

Goodbye сообщение

{
  "session_id": "xxx",
  "type": "goodbye"
}

3.3.2 Сервер→Устройство

Поддерживаемые типы сообщений соответствуют протоколу WebSocket, включая:

  • STT: Результаты распознавания речи
  • TTS: Управление синтезом речи
  • LLM: Управление эмоциональным выражением
  • MCP: Управление IoT
  • System: Системное управление
  • Custom: Пользовательские сообщения (опционально)

4. UDP аудиоканал

4.1 Установка соединения

После получения устройством MQTT Hello ответа, используется содержащаяся в нем информация о UDP соединении для установки аудиоканала:

  1. Анализ адреса и порта UDP сервера
  2. Анализ ключа шифрования и nonce
  3. Инициализация контекста шифрования AES-CTR
  4. Установка UDP соединения

4.2 Формат аудиоданных

4.2.1 Структура зашифрованного аудиопакета

|type 1byte|flags 1byte|payload_len 2bytes|ssrc 4bytes|timestamp 4bytes|sequence 4bytes|
|payload payload_len bytes|

Описание полей:

  • type: Тип пакета данных, фиксированный как 0x01
  • flags: Флаговые биты, в настоящее время не используются
  • payload_len: Длина полезной нагрузки (сетевой порядок байтов)
  • ssrc: Идентификатор источника синхронизации
  • timestamp: Временная метка (сетевой порядок байтов)
  • sequence: Порядковый номер (сетевой порядок байтов)
  • payload: Зашифрованные аудиоданные Opus

4.2.2 Алгоритм шифрования

Использование режима AES-CTR для шифрования:

  • Ключ: 128 бит, предоставляется сервером
  • Nonce: 128 бит, предоставляется сервером
  • Счетчик: Содержит информацию временной метки и порядкового номера

4.3 Управление порядковыми номерами

  • Отправитель: local_sequence_ монотонно возрастает
  • Получатель: remote_sequence_ проверяет непрерывность
  • Защита от повтора: Отклонение пакетов данных с порядковыми номерами меньше ожидаемого значения
  • Обработка ошибок: Разрешение незначительных пропусков порядковых номеров, запись предупреждений

4.4 Обработка ошибок

  1. Ошибка расшифровки: Запись ошибки, отбрасывание пакета данных
  2. Аномалия порядкового номера: Запись предупреждения, но обработка пакета данных продолжается
  3. Ошибка формата пакета данных: Запись ошибки, отбрасывание пакета данных

5. Управление состоянием

5.1 Состояние соединения

  stateDiagram
    direction TB
    [*] --> Disconnected
    Disconnected --> MqttConnecting: StartMqttClient()
    MqttConnecting --> MqttConnected: MQTT Connected
    MqttConnecting --> Disconnected: Connect Failed
    MqttConnected --> RequestingChannel: OpenAudioChannel()
    RequestingChannel --> ChannelOpened: Hello Exchange Success
    RequestingChannel --> MqttConnected: Hello Timeout/Failed
    ChannelOpened --> UdpConnected: UDP Connect Success
    UdpConnected --> AudioStreaming: Start Audio Transfer
    AudioStreaming --> UdpConnected: Stop Audio Transfer
    UdpConnected --> ChannelOpened: UDP Disconnect
    ChannelOpened --> MqttConnected: CloseAudioChannel()
    MqttConnected --> Disconnected: MQTT Disconnect

5.2 Проверка состояния

Устройство определяет доступность аудиоканала по следующим условиям:

bool IsAudioChannelOpened() const {
    return udp_ != nullptr && !error_occurred_ && !IsTimeout();
}

6. Параметры конфигурации

6.1 Конфигурация MQTT

Элементы конфигурации, читаемые из настроек:

  • endpoint: Адрес MQTT сервера
  • client_id: Идентификатор клиента
  • username: Имя пользователя
  • password: Пароль
  • keepalive: Интервал heartbeat (по умолчанию 240 секунд)
  • publish_topic: Тема публикации

6.2 Аудиопараметры

  • Формат: Opus
  • Частота дискретизации: 16000 Hz (сторона устройства) / 24000 Hz (сторона сервера)
  • Количество каналов: 1 (моно)
  • Длительность кадра: 60мс

7. Обработка ошибок и переподключение

7.1 Механизм переподключения MQTT

  • Автоматический повтор при неудаче соединения
  • Поддержка управления отчетами об ошибках
  • Запуск процесса очистки при разрыве соединения

7.2 Управление UDP соединением

  • Не автоматический повтор при неудаче соединения
  • Зависимость от повторного согласования через MQTT канал
  • Поддержка запроса состояния соединения

7.3 Обработка тайм-аута

Базовый класс Protocol предоставляет обнаружение тайм-аута:

  • Время тайм-аута по умолчанию: 120 секунд
  • Расчет на основе времени последнего получения
  • Автоматическая пометка как недоступного при тайм-ауте

8. Соображения безопасности

8.1 Шифрование передачи

  • MQTT: Поддержка шифрования TLS/SSL (порт 8883)
  • UDP: Использование шифрования AES-CTR для аудиоданных

8.2 Механизм аутентификации

  • MQTT: Аутентификация имя пользователя/пароль
  • UDP: Распространение ключей через MQTT канал

8.3 Защита от атак повтора

  • Монотонное возрастание порядковых номеров
  • Отклонение устаревших пакетов данных
  • Проверка временных меток

9. Оптимизация производительности

9.1 Управление параллелизмом

Использование мьютекса для защиты UDP соединения:

std::lock_guard<std::mutex> lock(channel_mutex_);

9.2 Управление памятью

  • Динамическое создание/уничтожение сетевых объектов
  • Управление аудиопакетами данных через умные указатели
  • Своевременное освобождение контекста шифрования

9.3 Сетевая оптимизация

  • Переиспользование UDP соединений
  • Оптимизация размера пакетов данных
  • Проверка непрерывности порядковых номеров

10. Сравнение с протоколом WebSocket

ОсобенностьMQTT + UDPWebSocket
Канал управленияMQTTWebSocket
АудиоканалUDP (зашифрованный)WebSocket (бинарный)
Реальное времяВысокое (UDP)Среднее
НадежностьСредняяВысокая
СложностьВысокаяНизкая
ШифрованиеAES-CTRTLS
Дружелюбность к файрволуНизкаяВысокая

11. Рекомендации по развертыванию

11.1 Сетевая среда

  • Обеспечить доступность UDP портов
  • Настроить правила файрвола
  • Рассмотреть NAT traversal

11.2 Конфигурация сервера

  • Конфигурация MQTT Broker
  • Развертывание UDP сервера
  • Система управления ключами

11.3 Метрики мониторинга

  • Коэффициент успешности соединения
  • Задержка передачи аудио
  • Коэффициент потери пакетов данных
  • Коэффициент неудач расшифровки

12. Заключение

Смешанный протокол MQTT + UDP реализует эффективную аудиосвязь через следующий дизайн:

  • Архитектура разделения: Разделение каналов управления и данных, каждый выполняет свою роль
  • Защита шифрования: AES-CTR обеспечивает безопасную передачу аудиоданных
  • Управление последовательностью: Предотвращение атак повтора и нарушения порядка данных
  • Автоматическое восстановление: Поддержка автоматического переподключения после разрыва соединения
  • Оптимизация производительности: UDP передача гарантирует реальное время аудиоданных

Этот протокол подходит для сценариев голосового взаимодействия с высокими требованиями к реальному времени, но требует компромисса между сложностью сети и производительностью передачи.

Связанная документация