Skip to main content

Message System

The Message module in LibXR is a high-performance, thread-safe messaging and processing mechanism based on the publish-subscribe model. It supports multiple subscription modes including synchronous, asynchronous, queued, and callback-based, with integrated data caching, validation, and packaging — making it a vital tool for module decoupling and real-time communication.


Features

  • Support for multiple subscribers receiving the same topic data;
  • Supports:
    • Synchronous subscription (blocking wait);
    • Asynchronous subscription (active polling);
    • Queued subscription (history caching);
    • Callback subscription (real-time response);
  • Internally uses Red-Black Tree + Lock-Free List for managing topics and subscribers;
  • Provides a standardized message packing and parsing mechanism, suitable for UART, CAN, network, etc.;
  • Supports data integrity checks, sticky packet handling, and fragmentation recovery.

Quick Start

Create a Topic and Publish a Message

auto domain = LibXR::Topic::Domain("sensor_data");
auto topic = LibXR::Topic::CreateTopic<float>("temperature", &domain, true);

float temp = 23.5f;
topic.Publish(temp);

Synchronous Subscription (Blocking)

float received_temp;
auto sync = LibXR::Topic::SyncSubscriber<float>("temperature", received_temp, &domain);

if (sync.Wait(1000) == ErrorCode::OK)
printf("Sync received temperature: %.2f\n", received_temp);

Asynchronous Subscription (Non-blocking)

auto async = LibXR::Topic::ASyncSubscriber<float>("temperature", &domain);

if (async.Available()) {
float latest_temp = async.GetData();
printf("Async received temperature: %.2f\n", latest_temp);
}
async.StartWaiting();

Queued Subscription (History Buffer)

LibXR::LockFreeQueue<float> queue(10);
auto que_sub = LibXR::Topic::QueuedSubscriber<float>("temperature", queue, &domain);

float temp;
if (queue.Pop(temp) == ErrorCode::OK)
printf("Queued received temperature: %.2f\n", temp);

Callback Subscription (Real-time Handling)

float latest_temp = 0.0f;
auto cb = LibXR::Topic::Callback::Create(
[](bool, void* arg, LibXR::RawData& data) {
*reinterpret_cast<float*>(arg) = *reinterpret_cast<float*>(data.addr_);
}, &latest_temp);

topic.RegisterCallback(cb);

Interface Overview

Class / MethodDescription
CreateTopic<T>()Create topic (with cache and checksum)
Publish()Publish data
SyncSubscriberWait synchronously for data
ASyncSubscriberRead latest data asynchronously
QueuedSubscriberPush to queue and retain history
RegisterCallback()Register a callback function
DumpData()Export cached or packed data
PackData()Manually construct a packed message
Server::ParseData()Parse and forward received data
Server::Register()Register a topic for parsing

Message Packing & Parsing

LibXR provides a unified format PackedData<T> and a server-side parser Server.

Pack Example

topic.Publish(36.5f);
LibXR::Topic::PackedData<float> pkt;
topic.DumpData(pkt);

Packet Format

FieldDescription
0xA5Fixed header
CRC32Topic name checksum
LengthData length (24 bits)
CRC8Header checksum
DataActual data
CRC8Tail checksum

Server-side Parsing Example

LibXR::Topic::Server server(512);
server.Register(topic);
server.ParseData(ConstRawData(pkt));

It automatically handles sticky/fragmented packets, validates data, and publishes valid data to the corresponding topic.


Data Export & PackData

Read Cached Data

double val = 0;
topic.DumpData(val); // Get the latest value

Pack as Network Format

LibXR::Topic::PackedData<double> pkt;
topic.DumpData(pkt); // With header + checksum

Manually Pack Arbitrary Data

double value = 123.45;
RawData src(value);
uint8_t buffer[128];
RawData dst(buffer, sizeof(buffer));

Topic::PackData(topic.GetKey(), dst, src);

Method Comparison Summary

ScenarioRecommended MethodUses CachePacked
Get latest valueDumpData(DataType)✅ Yes❌ No
Network packetDumpData(PackedData&)✅ Yes✅ Yes
Custom bufferDumpData<Mode>(...)✅ YesOptional
Manual packingPackData()❌ No✅ Yes

Application Scenarios

  • Structured message packaging and parsing over UART/network;
  • Efficient communication channel between MCU and main controller;
  • Data forwarding / logging / state synchronization;
  • Fragment recovery and asynchronous parsing support.

Notes

  • Topics with the same Domain name will reuse objects;
  • Topics with the same name in the same domain share instances and must be configured identically;
  • Topic is a lightweight wrapper and supports copying and passing;
  • If no data has been published, DumpData() will return ErrorCode::EMPTY;
  • PackData() can be used independently from cache — suitable for logging or simulated data generation.