Following What is MQTT Quality of Service blog post, it states that for QoS 1:
If the sender doesn’t receive the PUBACK packet within a reasonable time frame, it re-transmits the message to ensure its delivery.
However, the MQTT 5 specification’s delivery retry section states:
When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time
This information seems to be conflicting. I tested this functionality out with the HiveMQ MQTT Client library for Java (1.3.3) and noticed that even with manualAcknowledgement(true)
when subscribing to topics, the functionality described in the MQTT 5 specification was correct on the behavior… messages were only re-delivered on reconnects. I waited up to 45 seconds for an unacknowledged message to be re-delivered and it did not happen.
How then does QoS 1 guarantee delivery at least one time, if a client has to literally disconnect and reconnect before any message re-delivery attempts are made by the sender?