I came across this answer: https://stackoverflow.com/a/38094997/403875
But I'm not clear on what it means to "re-send in the order in which the PUBLISH packets were sent".
Suppose I send, "A", "B", "C" (all with QoS 1) and get back ACK's for "A" and "C" ("B" was lost). If I then re-send "B", the receiver will receive them out of order, won't they? So what does this restriction do? When does it apply? Does the sender need to re-send "B" and "C" to ensure that "C" is received last? What if this time it gets an ACK for "B", but not "C". Does it need to now send "C" again until it gets another "C" ACK?
I'm going to assume that all messages are sent on the same "ordered-topic" (throughout this answer) and that the server adheres to the MQTT spec. Given this you should only receive the PUBACK for:
because:
This means you should receive the
PUBACK
packets in the order you sent thePUBLISH
packets, or the connection should drop (and rules around resending packets come into play).It is possible, say due to a bug, that the server does not respond in the specified order. At this point the server is breaching the protocol (so any guarantees offered by the protocol no longer apply).
Say I send "ABCD" and receive an ACK for "A" followed by loss of connection. The above is simply saying that I should retransmit "BCD" in that order.
These rules may seem pretty simple but when you attempt to implement them things can become quite complex and various trade-offs need to be made. Consider a client that receives two
PUBLISH
messages and commits them both to a database. To speed processing we might start a separate thread to store the message and then trigger thePUBACK
. However this means that the second message might complete processing first - should we send the ACK immediately or wait? (the spec indicates thePUBACK
should be delayed).I think it's worth mentioning a key difference between the v3 and v5 specs here. The V3 spec allows an unacknowledged
PUBLISH
to be retransmitted at any time (the spec acknowledged issues with eatly TCP implementations - "Historically retransmission of Control Packets was required to overcome data loss on some older TCP networks"). The V5 spec only permits retransmission following a reconnection.Most servers/clients now follow the V5 rules; for example the Mosquitto change log for version 1.5 says:
The spec requires the underlying connection to provide "ordered, lossless, bi-directional connections", it does not include any requirements about the longevity of these connections. Connections will fail from time to time due to a wide variety of causes including:
The spec details how connectivity issues should be dealt with in detail (see keep alive, Operational behavior etc).