Dust DDS
S2E Software Systems implementation of the OMG Data Distribution Services (DDS) and Real-time Publisher-Subscriber (RTPS) protocols using the Rust programming language.
DDS is a middleware protocol and API standard for data-centric connectivity. The main goal of DDS is to share the right data at the right place at the right time, even between time-decoupled publishers and consumers.
This crate provide a high-quality Rust implementation of the minimum DDS profile. For high-quality it is meant that the implementation is done using stable Rust and without unsafe code and with large unit test code coverage.
The DDS type can be generated from an OMG IDL file using the dust_dds_gen crate.
Example
A basic example on how to use Dust DDS. The publisher side can be implemented as:
use dust_dds::{
domain::domain_participant_factory::DomainParticipantFactory,
infrastructure::{listeners::NoOpListener, qos::QosKind, status::NO_STATUS},
topic_definition::type_support::DdsType,
};
#[derive(DdsType)]
struct HelloWorldType {
#[dust_dds(key)]
id: u8,
msg: String,
}
fn main() {
let domain_id = 0;
let participant_factory = DomainParticipantFactory::get_instance();
let participant = participant_factory
.create_participant(domain_id, QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let topic = participant
.create_topic::<HelloWorldType>("HelloWorld", "HelloWorldType", QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let publisher = participant
.create_publisher(QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let writer = publisher
.create_datawriter::<HelloWorldType>(&topic, QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let hello_world = HelloWorldType {
id: 8,
msg: "Hello world!".to_string(),
};
writer.write(&hello_world, None).unwrap();
}
The subscriber side can be implemented as:
use dust_dds::{
domain::domain_participant_factory::DomainParticipantFactory,
infrastructure::{listeners::NoOpListener, qos::QosKind, status::NO_STATUS},
subscription::sample_info::{ANY_INSTANCE_STATE, ANY_SAMPLE_STATE, ANY_VIEW_STATE},
topic_definition::type_support::DdsType,
};
#[derive(Debug, DdsType)]
struct HelloWorldType {
#[dust_dds(key)]
id: u8,
msg: String,
}
fn main() {
let domain_id = 0;
let participant_factory = DomainParticipantFactory::get_instance();
let participant = participant_factory
.create_participant(domain_id, QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let topic = participant
.create_topic::<HelloWorldType>("HelloWorld", "HelloWorldType", QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let subscriber = participant
.create_subscriber(QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let reader = subscriber
.create_datareader::<HelloWorldType>(&topic, QosKind::Default, NoOpListener::new(), NO_STATUS)
.unwrap();
let samples = reader
.read(1, ANY_SAMPLE_STATE, ANY_VIEW_STATE, ANY_INSTANCE_STATE);
if let Ok(hello_world_samples) = samples {
println!("Received: {:?}", hello_world_samples[0].data().unwrap());
}
}
Sync and Async API
Dust DDS provides both a "sync" and an "async" API to allow integrating DDS in the largest number of applications with maximum performance. In general, the first option should be to use the sync API and make use of the DDS specified functionality such as listeners for event based programs. However, when implementing applications that already make use of async then the async API must be used. In particular, when using a Tokio runtime, using the Sync API will result in a panic due to blocking calls.
Release schedule
Dust DDS doesn't follow a fixed release schedule but we will make releases as new features are implemented.
License
This project is licensed under the Apache License Version 2.0.