Services
Services implement a Request/Reply (RPC) pattern, compatible with ROS2 semantics but running natively over the Minot network stack.
Golang Support
The mt_service library is written in Rust but it can be used from Golang as well. See our Go Guide on how to create a Go project for Minot.
Built on top of mt_pubsub, the mt_service crate provides robust request-reply communication with internal sequence tracking to ensure that responses are correctly matched to their corresponding requests.
After adding mt_service to your Cargo.toml, you can implement a service server and client.
Server
The server handles incoming requests and provides a response asynchronously.
service_server.rs
use mt_pubsub::{Node, NodeConfig};
use mt_service::ServiceServer;
use ros2_interfaces_jazzy_rkyv::std_msgs::msg;
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Node creation (auto-starts coordinator if needed)
let node = Arc::new(Node::create(NodeConfig::new("service_server")).await?);
let server = ServiceServer::<msg::String, msg::String>::new(
node.clone(),
"/my_service".to_owned()
).await?;
ServiceServer::start(
server,
Arc::new(|req: msg::String| async move {
println!("Got request: {}", req.data);
Ok(msg::String {
data: format!("Response to {}", req.data),
})
}),
).await;
Ok(())
}
Client
The client sends a request and waits for the response.
service_client.rs
use mt_pubsub::{Node, NodeConfig};
use mt_service::ServiceClient;
use ros2_interfaces_jazzy_rkyv::std_msgs::msg;
use std::sync::Arc;
use tokio::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let node = Arc::new(Node::create(NodeConfig::new("service_client")).await?);
let client = ServiceClient::<msg::String, msg::String>::new(
node.clone(),
"/my_service".to_owned()
).await?;
let request = msg::String {
data: "Hello from client".to_owned(),
};
match client.request(request, Some(Duration::from_secs(5))).await {
Ok(response) => println!("Got response: {}", response.data),
Err(e) => eprintln!("Service call failed: {}", e),
}
Ok(())
}