Framing and message headers
Each SBE packet can include two service headers:
- SOFH (Simple Open Framing Header);
- message header (defined in SBE template).
These headers carry packet metadata required for correct decode flow.
Simple Open Framing Header (SOFH)
SOFH usually includes:
- total message size;
- optional byte-order marker.
Exact format depends on venue.
SOFH selection during schema creation
SOFH policy is set when MessageSchema is created. You can use implicit or explicit selection.
Implicit SOFH selection
Implicit mode supports two built-in variants:
- standard SBE framing header;
- CME MDP3 framing header.
Standard SBE header is default:
// Standard SBE header
MessageSchema schema = new MessageSchema(ParseUtil.parse(new File("SbeTemplate.xml")));
Explicitly selecting standard header:
// Standard SBE header
MessageSchema schema = new MessageSchema(ParseUtil.parse(new File("SbeTemplate.xml")), false);
Selecting CME MDP3 header:
// MDP3 SOFH
MessageSchema schema = new MessageSchema(ParseUtil.parse(new File("CmeTemplate.xml")), true);
Explicit SOFH selection
Explicit mode is recommended for new integrations. You pass framing header specification directly to schema constructor.
Example with B3 header:
// Custom header
MessageSchema schema = new MessageSchema(ParseUtil.parse(new File("B3Template.xml")),
FramingHeaderPolicy.getCustomPolicy(FramingHeaderSpecification.B3_FRAMING_HEADER));
Predefined SOFH specifications
The library includes predefined specifications for known venues:
| Name | Description |
|---|---|
| SBE_BE_FRAMING_HEADER | Standard SBE header in big-endian format. |
| B3_FRAMING_HEADER | B3 SBE header. |
| CMEILINK3_FRAMING_HEADER | CME iLink3 SBE header. |
| CMEMDP3_FRAMING_HEADER | CME MDP3 SBE header. |
Creating custom SOFH
Before creating custom SOFH, define:
- field list and field offsets;
- byte order of each field;
- signed/unsigned type traits.
Current SOFH limitations:
- two fields only: size field and optional endian marker field;
- no extra user-defined fields.
Example SOFH:
- header byte order is little-endian;
- field 1: message size (
uint16); - field 2: standard 2-byte SBE endian marker.
Specification code:
public final static FramingHeaderSpecification MY_FRAMING_HEADER = new FramingHeaderSpecification(
// Size field specification
new FramingHeaderSpecification.FieldSpecification(
0, // Offset in the header
2, // Size of the field
false, // Unsigned
MessageSchema.Endianess.LittleEndian // Byte order of this field
),
// Message byte order marker specification
new FramingHeaderSpecification.EndianessFieldSpecification(
2, // Offset in the header
2, // Size of the field
false, // Unsigned
MessageSchema.Endianess.LittleEndian, // Byte order of the field
FramingHeaderSpecification.SBE_1_0_LE_LITTLEENDIAN_SIGN, // Mark for little-endian byte order of the message.
FramingHeaderSpecification.SBE_1_0_LE_BIGENDIAN_SIGN // Mark for big-endian byte order of the message.
)
);
Use custom SOFH in MessageSchema:
// Custom header
MessageSchema schema = new MessageSchema(ParseUtil.parse(new File("MyTemplate.xml")),
FramingHeaderPolicy.getCustomPolicy(MY_FRAMING_HEADER));
Message header
Message header stands before message body and defines service values like template ID and version. The base structure is declared in the XML template.
If the message header has only standard fields, encoder/decoder handles it automatically. If you add custom header fields, your code must read/write them explicitly.
Recommended APIs for custom header fields:
ByteDecoder always initializes required header fields during encoding.
Example: update custom message-header field via virtual ID
Resolve virtual field ID for custom header member:
String[] headerSequenceNoFieldPath = new String[] {
// Message header composite pseudo-name
SpecialFieldIds.MESSAGE_HEADER_FIELD_NAME,
// The message header field name
"SequenceNo"
};
// Get virtual ID of the 'SequenceNo' message header field
int seqNumID = schema.queryVirtualFieldId(headerSequenceNoFieldPath);
Create message and update/read this field:
byte[] data1 = new byte[SIZE_ENOUGH_TO_ENCODE];
IMessage msg1 = decoder.encode(data, 0, data.length, 1);
// Set the 'SequenceNo' message header field
msg1.setInt(seqNumID, 12345);
// Get the 'SequenceNo' message header field
int seqNum1 = msg1.getInt(seqNumID);
Java SBE Decoder