Перейти к основному содержимому
Нормативная версия документации - английская

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

Путь

Путь одного сообщения MQTT через сервис RustStream: цикл событий, задача соединения, доставка, обработчик, ответ и подтверждение.

Путь одного сообщения, на которое отвечают: вниз по левому столбцу от сервера к обработчику, вверх по правому столбцу обратно в сетьEventLoop::pollдекодирует PUBLISHЗадача соединениянаходит подпискуMqttMessageнагрузка общая, без копииДиспетчеродин цикл или воркерыДекодированиечтение из нагрузкиОбработчик-подписчикasync fn, #[subscriber]Сервер MQTTEventLoop пишетPUBLISH, затем PUBACKКанал запросовAsyncClientПодтверждениеPUBACK или PUBRECMqttPublisherпередаёт буферОтветкодируется в буфер
Схема текстом
  1. Сервер MQTT → EventLoop::poll декодирует PUBLISH
  2. EventLoop::poll декодирует PUBLISH → Задача соединения находит подписку
  3. Задача соединения находит подписку → MqttMessage нагрузка общая, без копии
  4. MqttMessage нагрузка общая, без копии → Диспетчер один цикл или воркеры
  5. Диспетчер один цикл или воркеры → Декодирование чтение из нагрузки
  6. Декодирование чтение из нагрузки → Обработчик-подписчик async fn, #[subscriber]
  7. Обработчик-подписчик async fn, #[subscriber] → Ответ кодируется в буфер
  8. Ответ кодируется в буфер → MqttPublisher передаёт буфер
  9. MqttPublisher передаёт буфер → Канал запросов AsyncClient
  10. MqttPublisher передаёт буфер → Подтверждение PUBACK или PUBREC: затем
  11. Подтверждение PUBACK или PUBREC → Канал запросов AsyncClient
  12. Канал запросов AsyncClient → EventLoop пишет PUBLISH, затем PUBACK
  13. EventLoop пишет PUBLISH, затем PUBACK → Сервер MQTT

Задача соединения опрашивает цикл событий rumqttc, который читает PUBLISH из сокета и декодирует его. Задача читает тему, находит подписки, к которым относится пакет протокола, как показывает страница Демультиплексирование, и отправляет каждой из них доставку по её собственному каналу. Тема, которая не является корректной строкой UTF-8, отбрасывается с предупреждением.

MqttMessage разделяет полезную нагрузку с пакетом протокола, поэтому тело никогда не копируется. Сообщение владеет копией темы и заголовками, построенными из свойств пакета. Доставка с QoS 1 или QoS 2 также хранит идентификатор пакета, который нужен её подтверждению. Контекст, который читает обработчик, тоже содержит тему.

У канала подписки нет собственного предела. Для QoS 1 и QoS 2 предел задаёт сервер: он отправляет не больше Receive Maximum неподтверждённых доставок. Пакет, к которому не подходит ни одна открытая подписка, ждёт подписку, которая откроется позже. Таких пакетов ждёт не больше 1024.

Ответ обработчика кодируется в буфер, и издатель передаёт этот буфер rumqttc как есть, без копирования. Заголовки становятся свойствами пакета. Публикация возвращает управление, когда запрос попал в канал запросов клиента, а не когда сервер его подтвердил.

Доставка завершается после ответа. Её подтверждение проходит через тот же канал запросов, поэтому уходит после ответа и до DISCONNECT более поздней остановки. Что отправляет каждый исход, показывает страница Завершение.

Бенчмарки считают этот путь: инструкции и выделения памяти одной доставки и одного ответа, включая работу клиента на потоке сервиса.