zenoh-tutorial

1.4K Views

August 07, 25

スライド概要

# この資料の目的
Zenohという通信基盤を、ただ“動かす”のではなく、
「なぜそれが存在するのか」「何を再定義しようとしているのか」まで踏み込んで
ぼくが語れるように(独断と偏見で) なるために作成した資料(間違っていても良い、まずはその入り口に入り、改善していくことが重要)

※ただし、まだ作成中です。気長に作っていきます。

# 対象読者
- C言語をマスターしている人
- ソケット通信とかROS通信とかわかっている人
- OSI参照モデルを知っている人
- 通信ミドルウェアの枠を超えて、構成・思想・自由を感じ取りたい人

# チュートリアルの出口:
- Zenoh の思想とアーキテクチャを理解できるようになる
- Zenoh プログラムをC言語で実装できるようになる
- Zenoh の応用例として、どんなのあるか理解できる

# 読者にとっての価値:
- Zenohの解釈を違った視点でわかる
- Zenohの通信プログラムを組める

profile-image

TOPPERS/箱庭WG活動でUnityやらAthrillやらmROSやら触ってます。 最近は仕事の関係でWeb系の技術に注力しつつ、箱庭への転用を模索しています。 2023年8月1日:合同会社箱庭ラボに移動しました

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

Zenoh Tutorial 合同会社箱庭ラボ CTO 森崇

2.

はじめに • この資料の目的 • Zenohという通信基盤を、ただ“動かす”のではなく、 • 「なぜそれが存在するのか」「何を再定義しようとしているのか」まで踏み込んで • ぼくが語れるように(独断と偏見で) なるために作成した資料(間違っていても良い、まずはその入り口に入り、改善していくことが重要) • 対象読者 • C言語をマスターしている人 • ソケット通信とかROS通信とかわかっている人 • OSI参照モデルを知っている人 • 通信ミドルウェアの枠を超えて、構成・思想・自由を感じ取りたい人 • チュートリアルの出口: • Zenoh の思想とアーキテクチャを理解できるようになる • Zenoh プログラムをC言語で実装できるようになる 読者にとっての価値: - Zenohの解釈を違った視点でわかる - Zenohの通信プログラムを組める • Zenoh の応用例として、どんなのあるか理解できる 2

3.

アジェンダ • Zenohとは? • Zenohの全体像 • Zenohの概念モデル • 環境構築 • チュートリアル 3

4.

Zenohとは? • ZettaScale Technology社が開発 • オープンソース(Eclipse Project)の通信プロトコルおよびミドルウェア • 特徴 • 低遅延・高スループット • 様々な通信機能 • 出版購読型、Key-Value Store に基づくデータ管理や計算処理の機能 • 柔軟なネットワーク構成 • Peer-to-Peer通信やNAT越えが可能 • 多種のプログラミング言語の対応 • Python や C/C++等 • Zenoh のコア機能は Rust によって実装されている 4

5.

公式ドキュメント • https://zenoh.io/ 5

6.

GitHubリポジトリ • https://github.com/eclipse-zenoh 6

7.

Zenohの全体像(ぼくの解釈) Zenohは、データ操作・通信手段・ネットワーク構成の すべてを民主化する次世代ミドルウェア データ操作の標準化 通信方式の選択性 通信構成の柔軟な対応 データ転送 トランスポート Entity pub /sub /get/reply QUIC, TLS, TCP, UDP(Unicast/Multicast) Client/Peer/Router データ検索 Network Topology query IPv4, IPv6, 6LoWPAN Mesh/Star/Tree データ永続化 Data Link Scouting put/store/get Wi-Fi, Ethernet, Bluetooth, Serial Multicasting/Gossip 7

8.

Zenohの概念モデル(ぼくの解釈) Communication Method Transfer Communication Protocol Entity Store Routing Entity Client Search Peer Transport Data Link Network Router Locator Autonomous Relay [凡例] 僕が勝手に 概念化したもの Zenoh 用語 Centralized Relay Tree Endpoint tcp/127.0.0.1:7447 地図に書かれた住所 Scouting が探すのは listen endpoint Mesh Star 住所に書かれたお店の入口 お店をUDPマルチキャストで探す Topology Topology は Endpoint の集合パターン Network Config Multicasting Scouting Gossip お店を探す方法 お店を情報をRoutingEntity が口コミで広げる 8

9.

pub/subの場合 データ入口 Client pub sub key (demo/example/zenoh-c-pub) Client Locator tcp/127.0.0.1:7447 connect Endpoint connect ネットワーク入口 listen Routing Entity Peer pub/sub の仲介 Router 9

10.

環境構築 • 環境構成 • ホスト:Windows WSL2(Ubuntu 24.04) • Docker Desktop for Windows node_a Docker Compose の設定により、node_r は L3 ルータとして動作し、 ユニキャストの IP パケットは転送される。 しかし、Linux の標準 ip_forward=1 はユニキャストのみ対象であり、 マルチキャストパケットは別ネットワークには転送されない。 そのため、local_net_1 内のマルチキャストは届くが、local_net_2 には到達しない。 node_b node_c 172.40.0.10 172.30.0.11 172.30.0.10 local_net_2 local_net_1 172.30.0.254 172.40.0.254 node_r(仮想L3スイッチ) 10

11.

インストール手順 • 前提とする環境 • Windows 11 • WSL2 (Windows Subsystem for Linux 2) • Ubuntu 24.04 LTS (WSL2) • Docker Desktop for Windows • 動作確認環境のインストール方法 • WSL2を起動する • git clone • git clone –recursive https://github.com/tmori/zenoh-tutorial.git • docker イメージ作成する • docker compose up –d 11

12.

インストールした環境の動作確認(1/3) • dockerイメージが作成されたことを確認しましょう。 • docker compose ps NAME IMAGE COMMAND SERVICE CREATED node_a zenoh-tutorial-node_a "sh -c '¥n for i in …" node_a 8 minutes ago node_b zenoh-tutorial-node_b "sh -c '¥n for i in …" node_b 8 minutes ago node_c zenoh-tutorial-node_c "sh -c '¥n for i in …" node_c 8 minutes ago node_r alpine:3.20 "sh -c '¥n apk add -…" node_r 10 minutes ago STATUS PORTS Up 8 minutes (unhealthy) 7447/tcp, 8000/tcp Up 8 minutes (unhealthy) 7447/tcp, 8000/tcp Up 8 minutes (unhealthy) 7447/tcp, 8000/tcp Up 8 minutes (healthy) 12

13.

インストールした環境の動作確認(2/3) • ノード接続確認 • docker exec -it node_a /bin/bash • docker exec -it node_b /bin/bash • docker exec -it node_c /bin/bash • docker exec -it node_r /bin/sh • ネットワーク接続確認 • node_a • node_bは接続 • node_cは接続 ping 172.30.0.11 ping 172.40.0.10 • node_b • node_aは接続 • node_cは接続 ping 172.30.0.10 ping 172.40.0.10 • node_c • node_aは接続 • node_bは接続 ping 172.30.0.10 ping 172.30.0.11

14.
[beta]
インストールした環境の動作確認(3/3)
• マルチキャスト接続確認

node_a:マルチキャスト送信する
while true; do echo "ping" | nc -w 1 -u 224.0.0.224 7446; sleep 1; done

node_b:マルチキャスト受信できる
tcpdump -i eth0 -nn udp and dst 224.0.0.224 and port 7446
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:49:52.625849 IP 172.30.0.10.50174 > 224.0.0.224.7446: UDP, length 5
08:49:54.629478 IP 172.30.0.10.51884 > 224.0.0.224.7446: UDP, length 5
08:49:56.633026 IP 172.30.0.10.37194 > 224.0.0.224.7446: UDP, length 5
08:49:58.636378 IP 172.30.0.10.57252 > 224.0.0.224.7446: UDP, length 5

node_r:eth0はマルチキャスト受信しているが、
eth1に転送されてない

node_c:マルチキャスト受信できない
(別ネットワークだから)

tcpdump -i eth0 -nn udp and dst 224.0.0.224 and port 7446

tcpdump -i eth0 -nn udp and dst 224.0.0.224 and port 7446

listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:56:27.010681 IP 172.30.0.10.33682 > 224.0.0.224.7446: UDP, length 5
08:56:29.014251 IP 172.30.0.10.52030 > 224.0.0.224.7446: UDP, length 5
08:56:31.017484 IP 172.30.0.10.47352 > 224.0.0.224.7446: UDP, length 5

tcpdump -i eth1 -nn udp and dst 224.0.0.224 and port 7446

15.

チュートリアル • 用意したZenoh-Tutorialリポジトリとインストール・ビルド等 • 動作確認 • 同一マシン内でのpub/sub通信 x 通信方式の選択(UDP/TCP) • 同一ネットワーク内でのpub/sub通信 x 通信方式の選択(UDP/TCP) • NAT超えでの pub/sub通信 x 通信方式の選択(UDP/TCP) • サンプルコード解説 15

16.

用意したZenoh-Tutorialリポジトリ • https://github.com/tmori/zenoh-tutorial

17.

リポジトリ内のコード概要 動作確認用の仮想環境 (docker compose) zenohのオリジナル・リポジトリ zenoh-c sample docker docker-compose.yml zenoh-cのサンプルコードとcmakeビルド環境 特徴: ・サンプルコードは、zenoh-cからコピー配置 →pub.c, sub.c ・zenohコードのビルド環境をサンプルとして同梱 zenoh-c-install zenoh-cのインストールディレクトリ

18.

zenoh-cのインストール手順 cd zenoh-c mkdir -p build cd build cmake .. -DCMAKE_INSTALL_PREFIX=/root/workspace/zenoh-c-install cmake --build . --config Release cmake --build . --target install Install the project... -- Install configuration: "Release" -- Installing: /root/workspace/zenoh-c-install/include -- Installing: /root/workspace/zenoh-c-install/include/zenoh_commons.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh_configure.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh_concrete.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh_constants.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh_memory.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh_macros.h -- Installing: /root/workspace/zenoh-c-install/include/zenoh_opaque.h -- Installing: /root/workspace/zenoh-c-install/lib/libzenohc.so -- Installing: /root/workspace/zenoh-c-install/lib/pkgconfig/zenohc.pc -- Installing: /root/workspace/zenoh-c-install/lib/libzenohc.a -- Installing: /root/workspace/zenoh-c-install/lib/cmake/zenohc/zenohcConfig.cmake -- Installing: /root/workspace/zenoh-c-install/lib/cmake/zenohc/zenohcConfigVersion.c

19.

サンプルコードのビルド cd sample/c-sample bash build.bash -- The C compiler identification is GNU 13.3.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- ZENOH_C_LIBRARY_PATH: /root/workspace/zenoh-c-install/lib/libzenohc.so -- Configuring done (0.1s) -- Generating done (0.0s) -- Build files have been written to: /root/workspace/sample/c-sample/cmake-build [ 25%] Building C object CMakeFiles/pub.dir/pub.c.o [ 50%] Linking C executable pub [ 50%] Built target pub [ 75%] Building C object CMakeFiles/sub.dir/sub.c.o [100%] Linking C executable sub [100%] Built target sub

20.

サンプルコードの概要 • pub.c • パブリッシャーコード • sub.c • サブスクライブコード pub.c key (demo/example/zenoh-c-pub) payload [文字列データ] attachment sub.c

21.
[beta]
同一マシン内でのpub/sub通信(TCP)
端末A(node_b):
./sample/c-sample /cmake-build/pub -c sample/c-sample /config-multicast.json
端末B(node_b):
./sample/c-sample /cmake-build/sub -c sample/c-sample /config-multicast.json

172.30.0.11

Peer A

node_b
Peer B

設定ファイル:config-multicast.json
{

}

"mode": "peer",
"scouting": {
"multicast": {
"enabled": true,
"address": "224.0.0.224:7446",
"interface": "auto",
"autoconnect": { "router": [], "peer": ["router", "peer"] },
"listen": true
}
}

scoutingの設定内容:
・enabled → そもそもマルチキャスト探索するか?
・ address → どのマルチキャストグループで?
・ interface → どの NIC で?
・ autoconnect → 発見したら自動で繋ぐ?誰に?
・ listen → 自分は見つかるように応答する?
ちなみに、
config-no-multicast.json
の場合は通信できないことも確認してみましょう。

21

22.
[beta]
同一マシン内でのpub/sub通信(UDP)
端末A(node_b):
./sample/c-sample /cmake-build/pub -c sample/c-sample /config-udp-connector.json
端末B(node_b):
./sample/c-sample /cmake-build/sub -c sample/c-sample /config-udp-listener.json

172.30.0.11

node_b

Peer A

設定ファイル:config-udp-connector.json

設定ファイル:config-udp-listener.json

{

{
"mode": "peer",
"connect": {
"endpoints": [
"udp/172.30.0.11:7446"
]
},
"scouting": {
"multicast": {
"enabled": false,
"address": "224.0.0.224:7446",
"interface": "auto",
"autoconnect": { "router": [], "peer": ["router", "peer"] },
"listen": true
}
}

}

Peer B

"mode": "peer",
”listen": {
"endpoints": [
"udp/172.30.0.11:7446"
]
},
"scouting": {
"multicast": {
"enabled": false,
"address": "224.0.0.224:7446",
"interface": "auto",
"autoconnect": { "router": [], "peer": ["router", "peer"] },
"listen": true
}
}
}

22

23.

同一ネットワーク内でのpub/sub通信(TCP) 端末A(node_a): ./sample/c-sample/cmake-build/pub --mode client -e tcp/172.30.0.11:7446 172.30.0.10 node_a Client A 端末B(node_b): ./sample/c-sample/cmake-build/sub --mode peer -l tcp/172.30.0.11:7446 Router ちなみに、Routerつけると、connectなしで通信できます。 端末A(node_a): ./sample/c-sample /cmake-build/pub --mode client Peer A 端末B(node_b): zenohd –l tcp/172.30.0.11:7466 172.30.0.11 node_b /sample/c-sample /cmake-build/sub --mode peer 23

24.

同一ネットワーク内でのpub/sub通信(UDP) 端末A(node_a): ./sample/c-sample/cmake-build/pub --mode client -e udp/172.30.0.11:7446 172.30.0.10 node_a Client A 端末B(node_b): ./sample/c-sample/cmake-build/sub --mode peer -l udp/172.30.0.11:7446 Router ちなみに、Routerつけると、connectなしで通信できます。 端末A(node_a): ./sample/c-sample /cmake-build/pub --mode client Peer A 端末B(node_b): zenohd -l udp/172.30.0.11:7446 & 172.30.0.11 node_b ./sample/c-sample /cmake-build/sub --mode peer 24

25.

NAT超えでの pub/sub通信(TCP) 172.30.0.10 172.30.0.11 node_a 172.40.0.10 node_c Client A Router Client C Client B node_b 端末A(node_a): ./sample/c-sample /cmake-build/pub --mode client -e tcp/172.40.0.10:7446 端末A(node_b): ./sample/c-sample /cmake-build/sub --mode client -e tcp/172.40.0.10:7446 ちなみに、Routerに接続しないと通信 できません。 端末C(node_c): zenohd -l tcp/172.40.0.10:7446 & ./sample/c-sample /cmake-build/sub --mode client 25

26.

NAT超えでの pub/sub通信(UDP) 172.30.0.10 172.30.0.11 node_a 172.40.0.10 node_c Client A Router Client C Client B node_b 端末A(node_a): ./sample/c-sample /cmake-build/pub --mode client -e udp/172.40.0.10:7446 端末A(node_b): ./sample/c-sample /cmake-build/sub --mode client -e udp/172.40.0.10:7446 ちなみに、Routerに接続しないと通信 できません。 端末C(node_c): zenohd -l udp/172.40.0.10:7446 & ./sample/c-sample /cmake-build/sub --mode client 26

27.

サンプルコード解説(sub側) コマンドオプションをZenohのコンフィグ ファイルに変換してローディングする keyexprに対応するコールバック関数 callbackを登録する データ受信待ちのループ 27

28.

サンプルコード解説(sub側) sub側のコールバック処理であり、最初 に、payloadを取り出しデコードする。 受信パケットの中身を デバッグ出力する アタッチメントがあれば、 その内容も出力する 28

29.

サンプルコード解説(pub側) コマンドオプションをZenohのコンフィグ ファイルに変換してローディングする keyexprをpublisherとして登録する。 購読者の有無を検知する “マッチングリスナー” を 登録(購読開始/終了イベントを受け取って送信 ON/OFF制御に使う) 29

30.

サンプルコード解説(pub側) 送信オプション構造体を既定値で初期化 ペイロードに送信データを設定する。アタッチメ ントがある場合はそれを付加する エンコーディング内容を設定する。この場 合は、text/plain ペイロードを送信する 30

31.
[beta]
サンプルコード解説(コマンド・オプション)
-k, --key <KEYEXPR> (optional, string, default='demo/example/zenoh-c-pub’):
The key expression to write to

-p, --payload <PAYLOAD> (optional, string, default='Pub from C!’):
The value to write

-a, --attach <ATTACHMENT> (optional, string, default=NULL):
The attachment to add to each put

-c, --config <CONFIG> (optional, string):
The path to a configuration file for the session. If this option isn't passed, the default configuration will be used.

-m, --mode <MODE> (optional, string, default='peer’):
The zenoh session mode. [possible values: peer, client, router]

-e, --connect <CONNECT> (optional, string):
Endpoint to connect to. Repeat option to pass multiple endpoints.
If none are given, endpoints will be discovered through multicast-scouting if it is enabled. e.g.: '-e tcp/192.168.1.1:7447'

-l, --listen <LISTEN> (optional, string):
Locator to listen on. Repeat option to pass multiple locators.
If none are given, the default configuration will be used. e.g.: '-l tcp/192.168.1.1:7447'

--no-multicast-scouting (optional):
By default zenohd replies to multicast scouting messages for being discovered by peers and clients.

31

32.

pub/subデータ構造(1/2) • Key expression(配送キー) どのトピック/キーに対するデータか。例:demo/video /frame、demo/**。 Pub/Sub/Query のマッチング単位になる。 • Kind(操作種別) PUT、DELETE、PATCH など。 受信側は z_sample_kind(sample) で取得し、削除通知や更新処理を区別。 • Payload(本体データ) そのキーに対して送信した「本体データ」。 ストレージ保存やクエリ応答など、Zenoh の基本機構が対象とする部分。 受信側は z_sample_payload(sample) で取得。 • Attachment(任意の追加データ) 本体とは別に運びたい付帯情報。 通常はストレージに保存されず、ルーティングや履歴には使われない。 送信側は options.attachment に設定、受信側は z_sample_attachment(sample) で取得。 例:メタ情報、サムネイル、署名、チェックサムなど。 • Encoding(内容種別ラベル) ペイロードの内容形式を MIME 型などで指定。例:text/plain、application/octet-stream。 送信側は options.encoding に設定、受信側は z_sample_encoding(sample) で取得。 受信処理の分岐やデコード判断に利用。 32

33.

pub/subデータ構造(2/2) • Timestamp / HLC(論理クロック) z_sample_timestamp(sample) で取得可能。 分散環境での時系列順序付けや重複排除に使用できる。 • QoS / Put オプション(送信側) z_publisher_put_options_default() で初期化し、必要に応じて encoding、attachment、priority、congestion_control 等を上書き。 • Matching listener(Publisher側の購読検知) z_publisher_declare_background_matching_listener() で、購読者が現れた/いなくなったイベントを受け取れる。 購読者の有無に応じて送信ON/OFF制御が可能。 • メモリ管理の注意 APIには z_owned_*(所有権あり→z_drop()で解放)と z_loaned_*(借用→解放不要)があり、z_move() で所有権移譲を行う。 33