В протоколе используются два обмена пакетами, чтобы обеспечить однозначную семантику обмена сообщениями QoS 2.
C --- PUBLISH --> S
*1
C <-- PUBREC --- S
*2
C --- PUBREL --> S
*3
C <-- PUBCOMP --- S
*4
Когда сервер получает PUBLISH
он хранит идентификатор и передает сообщение о. Когда сервер получает PUBREL
, он может удалить идентификатор.
Если соединение нарушается на *1
, клиент не знает, получил ли сервер сообщение. Он отправляет PUBLISH
(содержащий полную полезную нагрузку сообщения). Если сервер уже получил сообщение, ему просто нужно ответить PUBREC
.
Если соединение разрывается на *2
, клиент может получить или не получить PUBREC
. Если это не так, оно отправит PUBLISH
. В противном случае он отправит PUBREL
.
Если соединение нарушается на *3
, клиент не знает, получил ли сервер сообщение. Он отправляет PUBREL
- который не содержит полной полезной нагрузки сообщения.
Если соединение не работает *4
, и клиент не получил PUBCOMP
, он может отправить PUBREL
.
Есть два наблюдения для почему необходимы два обменов:
- сервер не требуется, чтобы помнить каждое сообщение, что когда-либо видел. Для хранения идентификатора сообщения существует очень четко определенный период. Обе биржи позволяют обеим сторонам быть уверенными, что сообщение доставлено ровно один раз.
- клиент не нужно повторно отправить ПУБЛИКОВАТЬ несколько раз (если соединение не прерывается при
*1
. Учитывая протокол предназначен для минимизации сетевого трафика, это важная особенность.
Я предполагаю, что это использует 4 пакетов чтобы избежать отправки отправителем первоначального пакета, а не только для того, чтобы не обрабатывать его в приемнике. – Hicaro