Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Путь
Путь одного сообщения MQTT через сервис RustStream: цикл событий, задача соединения, доставка, обработчик, ответ и подтверждение.
Схема текстом
- Сервер MQTT → EventLoop::poll декодирует PUBLISH
- EventLoop::poll декодирует PUBLISH → Задача соединения находит подписку
- Задача соединения находит подписку → MqttMessage нагрузка общая, без копии
- MqttMessage нагрузка общая, без копии → Диспетчер один цикл или воркеры
- Диспетчер один цикл или воркеры → Декодирование чтение из нагрузки
- Декодирование чтение из нагрузки → Обработчик-подписчик async fn, #[subscriber]
- Обработчик-подписчик async fn, #[subscriber] → Ответ кодируется в буфер
- Ответ кодируется в буфер → MqttPublisher передаёт буфер
- MqttPublisher передаёт буфер → Канал запросов AsyncClient
- MqttPublisher передаёт буфер → Подтверждение PUBACK или PUBREC: затем
- Подтверждение PUBACK или PUBREC → Канал запросов AsyncClient
- Канал запросов AsyncClient → EventLoop пишет PUBLISH, затем PUBACK
- EventLoop пишет PUBLISH, затем PUBACK → Сервер MQTT
Задача соединения опрашивает цикл событий rumqttc, который читает PUBLISH из сокета и
декодирует его. Задача читает тему, находит подписки, к которым относится пакет протокола, как
показывает страница Демультиплексирование, и отправляет каждой из них
доставку по её собственному каналу. Тема, которая не является корректной строкой UTF-8,
отбрасывается с предупреждением.
MqttMessage разделяет полезную нагрузку с пакетом
протокола, поэтому тело никогда не копируется. Сообщение владеет копией темы и заголовками,
построенными из свойств пакета. Доставка с QoS 1 или QoS 2 также хранит идентификатор пакета,
который нужен её подтверждению. Контекст, который читает
обработчик, тоже содержит тему.
У канала подписки нет собственного предела. Для QoS 1 и QoS 2 предел задаёт сервер: он отправляет не больше Receive Maximum неподтверждённых доставок. Пакет, к которому не подходит ни одна открытая подписка, ждёт подписку, которая откроется позже. Таких пакетов ждёт не больше 1024.
Ответ обработчика кодируется в буфер, и издатель передаёт
этот буфер rumqttc как есть, без копирования. Заголовки становятся свойствами пакета. Публикация
возвращает управление, когда запрос попал в канал запросов клиента, а не когда сервер его
подтвердил.
Доставка завершается после ответа. Её подтверждение проходит через тот же канал запросов, поэтому уходит после ответа и до DISCONNECT более поздней остановки. Что отправляет каждый исход, показывает страница Завершение.
Бенчмарки считают этот путь: инструкции и выделения памяти одной доставки и одного ответа, включая работу клиента на потоке сервиса.