はじめに
最近私の中でアツい「Zenoh」を使おうとしてみた記録です。
とても軽い気持ちで書いているので優しくしてください。
Rustで実装されたため他のクレートと組み合わせて、色々できそうです。
基本的なPub/Sub
論よりコードということで、実装していきます。
cargo new zenoh_pubsub
パッケージを作成したら、以下のように追加してください。これでzenohを扱うことができます。
また、async-stdは非同期システムを作成する際のクレートでこれも書いときます。
[dependencies]
zenoh = "0.7.0-rc"
async-std = "1.0"
今回は一つのパッケージ内にpublisherとsubscriberの両方を実装するため、srcディレクトリ内のmain.rsを削除し、srcディレクトリ内にbinディレクトリを作成してください。
その後publisherを以下のように実装します。
use zenoh::{
config::Config,
prelude::r#async::*,
};
use async_std;
#[async_std::main]
async fn main() {
let session = zenoh::open(Config::default()).res().await.unwrap();
let keyexpr = "test".to_string();
let publisher = session.declare_publisher(&keyexpr).res().await.unwrap();
let mut count = 0;
loop {
let msg = format!("Hello, World:{}", count);
publisher.put(msg).res().await.unwrap();
count += 1;
}
}
とてもシンプルな実装ですね。
まずsessionというものをつくります。zenohではどうやら通信に設定を設けることができるらしいです。しかし今回はデフォルトで使います。
ROSではトピックというものを決めていたようにkey exprをStringでつくります。
次がpublisherの定義をしている行です。
let publisher = session.declare_publisher(&keyexpr).res().await.unwrap();
特別なことは特になくて
あとはループの中でput(publish)するだけですね。
publisher.put(msg).res().await.unwrap();
Rustなこともあって短いコーディング量で実装できました。
次はSubscriber側です。
use zenoh::{
config::Config,
prelude::r#async::*,
};
use async_std;
#[async_std::main]
async fn main()
{
let session = zenoh::open(Config::default()).res().await.unwrap();
let keyexpr = "test".to_string();
let subscriber = session.declare_subscriber(&keyexpr).res().await.unwrap();
loop {
let sample = subscriber.recv_async().await.unwrap();
println!("Subscribe:{}", sample.value.to_string());
}
}
publisherのときと同じkey exprにすることで送受信ができます。
あとはループ内で非同期的に待ってもらうだけです。
最終的には以下のようなディレクトリ構造になりました。
- zenoh_pubsub
- Cargo.toml
- src
- bin
- pub_test
- sub_test
- bin
実行する
まずはビルドです。
zenoh_pubsubディレクトリ内に入ってからビルドしてください。
cd zenoh_pubsub
cargo build
少し時間がかかると思います。
ビルドが完了したらようやく実行です。他のRustのプログラムと同じでcargo run を使います。
まずはSubscriber
cargo run --bin sub_test
そして、別のタブを開きpublisherを実行してください
cargo run --bin pub_test
最後にsubscriberを実行したタブで以下のようなログを確認できたらOKです。
Subscribe:Hello, World:62284
Subscribe:Hello, World:62285
Subscribe:Hello, World:62286
Subscribe:Hello, World:62287
Subscribe:Hello, World:62288
Subscribe:Hello, World:62289
Subscribe:Hello, World:62290
Subscribe:Hello, World:62291
Subscribe:Hello, World:62292
Subscribe:Hello, World:62293
Subscribe:Hello, World:62294
Subscribe:Hello, World:62295
Subscribe:Hello, World:62296
Subscribe:Hello, World:62297
Subscribe:Hello, World:62298
Subscribe:Hello, World:62299
Subscribe:Hello, World:62300
Subscribe:Hello, World:62301
Subscribe:Hello, World:62302
Subscribe:Hello, World:62303
Subscribe:Hello, World:62304
Subscribe:Hello, World:62305
Subscribe:Hello, World:62306
Subscribe:Hello, World:62307
Subscribe:Hello, World:62308
Subscribe:Hello, World:62309
Subscribe:Hello, World:62310
Subscribe:Hello, World:62311
Subscribe:Hello, World:62312
Subscribe:Hello, World:62313
どこにもsleepを入れてないので早すぎますね(笑)。
最後に
zenohについてとても基本的な実装してみました。
Rustには他にSerial通信をするクレートがあるためつなげてみるのも面白そうですが、zenoh側で実装済みのものがありそうなのでそちらを先に調べてみようかなと思っています。ROSともつながるらしくsensorの情報はそっちから受信できたらいいのかな?
また、機会があったら記事にします。