PUBLISH
Publish a message
The PUBLISH message is the means by which a client sends a message to a
broker for distribution to interested subscribers. Each published message
is associated with a Topic Name (sometimes known elsewhere as Subject
or Channel).
This is a hierarchical name space defining a taxonomy of information
sources that subscribers can register an interest in. Any message published
to a given Topic Name will be delivered to any connected subscribers who
have subscribed to that Topic.
Note that to maintain symmetry, if a client subscribes to one or more
Topics, then any messages published to those Topics will be delivered from
the broker to the client in the form of a PUBLISH message.
Fixed Header
See the Fixed Header section for more information,
bit |
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
byte 1 |
Message Type (3)
|
DUP flag
|
QoS level
|
RETAIN
|
|
0
|
0
|
1
|
1
|
0
|
0
|
1
|
0
|
byte 2 |
Remaining Length
|
The example shown above indicates QoS level 1, first transmission (DUP
clear), do not retain.
QoS level
The QoS bits define the Quality of Service requirements for this publication.
The defined values for the QoS field are specified in the Fixed
Header section, and their meanings are discussed in the QoS
section.
DUP flag
For messages of QoS 1 or QoS 2, the DUP bit should be set if this is a
message that is being retransmitted after the detection of some kind of
failure. This indicates to the broker that it may be a duplicate of a message
already received. The significance of this information to the broker depends
upon the QoS level. If this is the first sending of the message, the DUP
bit should be clear. For QoS 0, the DUP bit is not used.
RETAIN flag
The RETAIN flag is an indication to the broker that this message should
be held, if possible, in the broker, and should be sent to any new
subscriber to this Topic as an initial message. This allows a complete
"current state" of a number of Topics to be quickly established by a new
client upon connecting to the broker. This is particularly useful if publishers
are only sending messages on a "Report By Exception" basis: it may be a
very long time before a new subscriber receives any data on a particular
Topic. The data is known as the "Retained", or "Last Known Good"
(LKG) value.
After a SUBSCRIBE to one or more Topics,
a subscriber will receive a SUBACK, and then
one message for each of the newly subscribed Topics for which there is
currently a Retained value. The Retained value is published from the broker
to the subscriber with the RETAIN flag set, and with the same QoS
with which it was originally published, and so will be subject to the usual
QoS delivery assurances. The RETAIN flag is set in the message to the subscribers
to distinguish it from "live" data, so that it can be handled appropriately
by the subscriber.
Note that there is no guarantee that a previous Retained PUBLISH to
the broker will still be held by the broker, and so the subscriber might
not receive an initial Retained PUBLISH on a Topic.
Remaining Length
The Remaining Length is the length of the Variable Header plus the length
of the Payload.
This may be a multi-byte field. See the Fixed
Header section for more details.
Variable Header
The Variable Header portion of the PUBLISH message contains the Topic Name
and possibly a Message Identifier, if the QoS level is 1 or 2.
Topic Name
The Topic Name is a UTF-encoded string. If Topic Name Compression is available,
then this field may (at the option of the client) be compressed. See the
Variable
Header section for more information. Note that in this level of the
protocol, however, Topic Name Compression is not available.
Message Identifier
This field is only present for messages of QoS 1 and QoS 2 (see the QoS
section for more details). It should be noted that typically the protocol
library would take responsibility for generating this identifier, and passing
it back to the publishing application, possibly as a return handle. This
approach avoids the risk of duplicate Message Identifiers being generated
by multiple applications, or multiple publishing threads, running on a
single client.
For QoS 0, Message Identifier is not used, and must not appear
in the Variable Header.
The Message Identifer is a 16 bit unsigned integer, which will typically
increase, but is not required to increase
by exactly one from one message to the next.
The ordering of the 2 bytes of the Message Identifier is MSB, then
LSB (big-endian).
Message ID 0 (i.e. 0x0000) is reserved as an invalid Message ID, and
must not be used.
See the Variable Header section for
more information.
Example:
Topic Name: |
"a/b" |
QoS level |
1 |
Message ID: |
10 |
The format of the Variable Header in this case would be:
|
Description |
7 |
6
|
5
|
4
|
3
|
2
|
1
|
0
|
Topic Name |
byte 1 |
Length MSB (0) |
0 |
0
|
0
|
0
|
0
|
0
|
0
|
0
|
byte 2 |
Length LSB (3) |
0 |
0
|
0
|
0
|
0
|
0
|
1
|
1
|
byte 3 |
'a' (0x61)
|
0 |
1
|
1
|
0
|
0
|
0
|
0
|
1
|
byte 4 |
'/' (0x2F)
|
0 |
0
|
1
|
0
|
1
|
1
|
1
|
1
|
byte 5 |
'b' (0x62)
|
0 |
1
|
1
|
0
|
0
|
0
|
1
|
0
|
Message Identifier |
byte 6 |
Message ID MSB (0) |
0 |
0
|
0
|
0
|
0
|
0
|
0
|
0
|
byte 7 |
Message ID LSB (10) |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
Payload
The Payload portion of a PUBLISH message contains the data to be published.
Its content and format is completely application specific. Note that the
Remaining Length field in the Fixed Header includes both the Variable Header
length and the Payload length.
Response
The response from the recipient to a PUBLISH message depends on the Quality
of Service level specified. See the QoS section
for more details.The expected responses are as follows:
Actions
Since PUBLISH messages can be sent either from a publisher to the broker,
or from the broker to a subscriber, it is worthwhile describing what is
expected of the recipient of a PUBLISH message. In the case of the broker
receiving the message, "interested parties" means subscribers to the topic
of the PUBLISH. In the case of a subscriber receiving the message, "interested
parties" means the application on the client which has subscribed to one
or more topics, and is waiting for a message from the broker.
Upon receipt of a QoS 0 message, the recipient should make the message
available to any "interested parties".
Upon receipt of a QoS 1 message, the recipient should log the message
to persistent storage, make it available to any "interested parties",
and return a PUBACK response to the sender.
For a QoS 2 message, the recipient should log the message to persistent
storage, but not yet make it available to "interested parties". The recipient
should then return a PUBREC message to the sender.
Further discussion of the actions that the client and broker should
perform upon receipt of messages of QoS 1 and QoS 2 appears in the Protocol
Flow section.
Discussion
-
ASC on SEC flag
-
After a long discussion with Chris Sharp, it was decided that the SECurity
flag has no place in the protocol, so its bit position can safely be given
up to the RETAIN flag. The reasoning is as follows: Authentication
of a particular client, possibly using certificate exchange, etc, belongs
at the session level, and therefore will appear in the CONNECT verb. Encryption
is an application-level thing, and therefore belongs purely in the payload
- the broker has no interest in whether or not a publisher has decided
to encrypt one of its messages.
-
ASC on Message ID 0
-
If a PUBLISH message is incorrectly constructed, it is possible for a MID
of 0 to appear. Consequently it is reserved as an invalid Message ID to
help to discover such errors.
-
AN on PUBACK return codes
-
Should we add an error return code to the PUBACK messages, so that the
broker has a way of flagging to the client a syntactic error in a publish,
such as publishing on QoS3, for example?
-
ASC comment
-
We have decided not to do that, as it is specifying client/broker behaviour,
which is not in the scope of the protocol specification.
-
ASC on batching
-
Is batching of messages required or done in device? e.g. Multiple
publishes to same topic batched into one message, or publishes to multiple
topics chained together in payload to minimise average header overhead.
-
AN comment
-
No. This is often implemented by the application in the form of a "report"
with a known format; in effect moving the batching to the application level.
-
ASC on publish flow control
-
One option we may consider is the notification of a publisher if there
are no subscribers to a topic that has been published to. This would potentially
save wasted effort on the part of the client, network utilisation, and
broker traffic. There would, of course, then need to be a corresponding
notification when a subscriber selected one of the "stopped" topics. Also,
this would complicate the protocol flow, as there would now be the possibility
of an unsolicited response to a publish of QoS 0 - At Most Once - where
no response would be expected. However, the advantages may outweigh the
disadvantages. We would value thoughts from Arcom experience on this.
-
Comment
-
This type of feedback would typically be implemented at the application
level; i.e. there is no requirement for it to be explicitly included in
the protocol layer. The downside to such an approach, when there are many
thousands of remote publishing clients, is that there is the danger of
a storm of outbound notification messages if a subscriber connects with
a wild-carded Topic Name.
-
TNH on broker to client PUBLISH
-
The use of a PUBLISH message for messages from the broker to the client
is not consistent with other pub/sub APIs. However, as this is acknowledged
to be a specialised protocol, specifically for the purpose of communication
between remote, low-end devices and a message broker, and since the SUBSCRIBE
by a client is really just a way of mapping the traditional "command flow"
from broker to client into a pub/sub paradigm, then we can probably follow
this approach.
BACK to index
Last Modified: 19-Oct-99