Skip to content

eclipse-ecal/rustecal

Repository files navigation

rustecal

Rust bindings for the high-performance eCAL middleware, providing efficient pub/sub and service-based communication for interprocess and distributed systems.


Features

  • Idiomatic Rust interface to the eCAL API
  • Zero-copy shared memory transport
  • Type-safe publish/subscribe and service communication
  • Modular type support: String, Binary, Protobuf
  • Fully runtime-compatible with C++ eCAL systems

Examples

Publisher

use std::time::Duration;
use rustecal::{Ecal, EcalComponents, TypedPublisher};
use rustecal_types_string::StringMessage;

fn main() {
    // eCAL init
    Ecal::initialize(Some("hello publisher"), EcalComponents::DEFAULT).unwrap();

    // create a string publisher on "hello"
    let publisher = TypedPublisher::<StringMessage>::new("hello").unwrap();

    // prepare the message to send
    let message = StringMessage("Hello from Rust!".to_string());

    // publish until eCAL shuts down
    while Ecal::ok() {
        publisher.send(&message);
        std::thread::sleep(Duration::from_millis(500));
    }

    // clean up and finalize eCAL
    Ecal::finalize();
}

Subscriber

use rustecal::{Ecal, EcalComponents, TypedSubscriber};
use rustecal_types_string::StringMessage;
use rustecal::pubsub::typed_subscriber::Received;

fn main() {
    // eCAL init
    Ecal::initialize(Some("hello subscriber"), EcalComponents::DEFAULT).unwrap();

    // create a string subscriber on “hello”
    let mut subscriber = TypedSubscriber::<StringMessage>::new("hello").unwrap();

    // print each incoming message
    subscriber.set_callback(|msg: Received<StringMessage>| {
        let StringMessage(text) = msg.msg;
        println!("Received: {}", text);
    });

    // keep the thread alive so callbacks can run
    while Ecal::ok() {
        std::thread::sleep(std::time::Duration::from_millis(100));
    }

    // clean up and finalize eCAL
    Ecal::finalize();
}

Service Server

use std::time::Duration;
use rustecal::{Ecal, EcalComponents};
use rustecal::service::server::ServiceServer;
use rustecal::service::types::MethodInfo;

fn main() {
    // eCAL init
    Ecal::initialize(Some("mirror server"), EcalComponents::DEFAULT).unwrap();

    // create a service server for "mirror"
    let mut server = ServiceServer::new("mirror").unwrap();

    // register the "reverse" method
    server
        .add_method(
            "reverse",
            Box::new(|_info: MethodInfo, req: &[u8]| {
                let mut reversed = req.to_vec();
                reversed.reverse();
                reversed
            }),
        )
        .unwrap();

    // keep the server alive to handle incoming calls
    while Ecal::ok() {
        std::thread::sleep(Duration::from_millis(100));
    }

    // clean up and finalize eCAL
    Ecal::finalize();
}

Service Client

use std::time::Duration;
use rustecal::{Ecal, EcalComponents};
use rustecal::service::client::ServiceClient;
use rustecal::service::types::ServiceRequest;

fn main() {
    // eCAL init
    Ecal::initialize(Some("mirror client"), EcalComponents::DEFAULT).unwrap();

    // create a service client for "mirror"
    let client = ServiceClient::new("mirror").unwrap();

    // call the "reverse" service until eCAL shuts down
    while Ecal::ok() {
        // prepare the request payload
        let request = ServiceRequest {
            payload: b"stressed".to_vec(),
        };

        // send the request and print the response if any
        if let Some(response) = client.call("reverse", request, Some(1000)) {
            println!("Reversed: {}", String::from_utf8_lossy(&response.payload));
        } else {
            println!("No response received.");
        }

        // throttle the request rate
        std::thread::sleep(Duration::from_secs(1));
    }

    // clean up and finalize eCAL
    Ecal::finalize();
}

Documentation

Full user guide: https://eclipse-ecal.github.io/rustecal

cd docs/
mdbook serve

License

Licensed under Apache-2.0.


Maintainer

Rex Schilasky