Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Качество обслуживания
MQTT подтверждает доставку одним пакетом протокола при QoS 1 и обменом из четырёх пакетов при QoS 2; этот крейт отправляет подтверждение, когда обработчик завершил работу.
Схема текстом
- QoS 0: не более одного раза: PUBLISH; Вызов обработчика
- QoS 1: хотя бы один раз: PUBLISH; Вызов обработчика; PUBACK при ack
- QoS 2: ровно один раз: PUBLISH; Вызов обработчика; PUBREC при ack; PUBREL; PUBCOMP сам rumqttc
- Сервер MQTT: PUBLISH; PUBLISH; PUBLISH; PUBREL
- Этот сервис: Вызов обработчика; Вызов обработчика; PUBACK при ack; Вызов обработчика; PUBREC при ack; PUBCOMP сам rumqttc
- PUBLISH → Вызов обработчика
- PUBLISH → Вызов обработчика
- Вызов обработчика → PUBACK при ack
- PUBLISH → Вызов обработчика
- Вызов обработчика → PUBREC при ack
- PUBREC при ack → PUBREL
- PUBREL → PUBCOMP сам rumqttc
Качество обслуживания выбирается дважды: издатель выбирает его для своего сообщения, а подписка -
для того, что она принимает. Доставка идёт на меньшем из двух уровней, поэтому публикация с QoS 0
доходит до подписки с QoS 1 на уровне QoS 0. Qos
дескриптора задаёт сторону подписки, а политика публикации -
сторону сообщения.
При QoS 0 сервер отправляет PUBLISH и забывает о нём. Обратно ничего не передаётся, поэтому у
доставки с QoS 0 нечего подтверждать: ack возвращает AckError::Unsupported, и рантайм
записывает это в журнал.
При QoS 1 и QoS 2 сервер хранит сообщение, пока сервис не ответит. Этот крейт подключается с
ручными подтверждениями, поэтому rumqttc передаёт каждый PUBLISH подписке и сам ничего не
отправляет. Подтверждение уходит, когда доставка
подтверждена, после возврата из обработчика: PUBACK при QoS 1, PUBREC при QoS 2. PUBREL и PUBCOMP,
которые завершают QoS 2, rumqttc передаёт сам.
В MQTT нет отрицательного подтверждения. Доставка с QoS 1 или QoS 2, которую сервис так и не подтвердил, остаётся на сервере. Сервер отправляет её повторно, с пометкой дубликата, только когда постоянная сессия возобновляется на новом соединении. Это возобновление показывает страница Сессии, а что отправляет каждый исход обработчика - страница Завершение.
При подключении клиент объявляет Receive Maximum: сколько доставок с QoS 1 и QoS 2 он принимает
без подтверждения. Когда столько доставок ждут подтверждения, сервер не отправляет по этому
соединению новых сообщений с QoS 1 и QoS 2, пока одна из них не подтверждена. По умолчанию этот
крейт объявляет 1000, а receive_maximum меняет это число.
Окно ограничивает число сообщений, которые ждут медленную подписку. Доставки с QoS 0 в нём не участвуют.
Публикация из сервиса возвращает управление, когда rumqttc поместил сообщение в свой канал
запросов на 64 запроса, а не когда сервер его подтвердил. Каждая публикация с QoS 1 и QoS 2
хранится, пока сервер её не подтвердит. Если после переподключения сессия сохранилась, rumqttc
отправляет их повторно, как предписывает протокол. Если переподключение начинает новую сессию,
задача соединения отправляет их заново как новые публикации. Сервер не может узнать сообщение,
которое уже получил, поэтому такое сообщение может прийти дважды, даже при QoS 2.
Порядок обмена задаёт сам протокол, разделы 4.3 и 4.9 стандарта MQTT 5.0.