Message Body
IOTMP Message Body
The message body, also known as the payload, is the portion of a message that contains the actual data being transmitted. It follows the header and contains the information that the sender intends to send to the receiver.
Key-Value Pairs
Each IOTMP message consists basically on a series of key-value
pairs. When a message is encoded, the keys and values are concatenated into a byte stream. When the message is decoded, the parser needs to be able to skip fields that it doesn't recognize. This way, new fields can be added to a message without breaking old programs that do not know about them. To this end, the "key" for each pair in a wire-format message is actually two values – the field number according to each message definition, plus a Wire-Type, that provides just enough information to find the length of the following value.
So, the message body is composed of a variable number of fields, each one with a key-value pair:
Field | Type | Description |
---|---|---|
Specifies the field identifier and the value type. | ||
Contains the actual payload of the field. |
Key
Each key in the message is a varint that encodes both the Field Identifier, and the Wire type.
A Field Identifier represents just the field for each specific message, i.e., if the value is related with a stream identifier, a parameter, or a payload.
The Wire Type specifies how the value is encoded over the wire, as each body value can be encoded in different formats depending on the client and server implementation.
Then, a Key (with both Field Identifier and Wire Type) is encoded as a varint, where the first 3 bits indicates the Wire-Type, and the 4 remaining bits indicates the Field Identifier. This schema is described below:
For example, a key with a wire-type (0) and a field identifier (1) would be encoded as the following:
It is possible to use a varint of two or more bytes in order to extend the field identifier. But in general terms, one byte covers up to 2^4 (16) Field Identifiers, and up to 2^3 (8) Wire Types, that should be enough for most use-cases.
The following wire types are supported by default inside IOTMP:
Wire Type
The wire type specifies the format used for encoding each data field. IOTMP relies on JSON format or its derivates, so, different JSON encoding formats can be supported on an IOTMP server, i.e., JSON, PSON, MessagePack, CBOR, etc. This way, different client implementations can choose the preferred encoding format, according to their needs, library availability, etc. The default encoding formats that an IOTMP server MUST support are PSON, and JSON.
An IOTMP client MUST support at least one of the default formats: PSON or JSON. It is always preferred PSON encoding, as it can improve the overall performance by reducing serialization and deserialization complexity, and reduces bandwidth with a more compact representation. JSON encoding can be used by convenience, i.e., when running IOTMP inside a browser.
By default, IOTMP specifies 4 different wire types:
Varint (0x00): Indicates that the value holds an integer encoded as varint.
PSON (0x01): Indicates that the value holds a JSON encoded with PSON.
JSON (0x02): Indicates that the value holds a JSON without any binary encoding.
Negotiated (0x07): Indicates that the value holds a JSON encoded with a negotiated binary representation, i.e., MessagePack, CBOR, UBJSON.
Type | Value | Used For |
---|---|---|
Varint | 0x00 | Positive number encoded as varint. It is heavily used in the protocol for specifying fields like the stream identifier. |
PSON | 0x01 | Value is encoded in PSON format. As PSON supports streaming decoding, the payload is encoded right away after the key. |
JSON | 0x02 | Value is encoded in JSON format. The value is composed by a varint (specifying total payload size) + the custom JSON payload. |
Reserved | 0x03 to 0x06 | Reserved for future usage. |
Negotiated | 0x07 | Value is encoded in the negotiated encoding format (see Connect Message). The value is composed by a varint (specifying total value size) + the custom encoded payload. |
It is preferred to use PSON encoding format when possible, as it reduces encoding/decoding complexity, and reduces overall bandwidth.
Field Identifier
The field identifier depends on each message, so, each one specifies their own message identifiers, as described here.
Value
Each field with a key has an associated value that can be encoded in different formats, according to the specification provided on the Wire-Type.
Last updated