LoginSignup
10
2

はじめてNerves(13) Elixir API の Zenohex を使って Zenoh で Pub/Sub してみる

Last updated at Posted at 2023-12-30

これは #NervesJP Advent Calendar 2023 の23日目です。昨日は @myasu さんの ElixirでGUI・Scenic [新・入門編] でした。

はじめに

去年あたりから Zenoh という言葉を聞くようになりました。どうやら素敵な Pub/Sub のプラットフォームのようです。IoT でのプログラミングに Pub/Sub は欠かせないので大変気になります。

それでもって本家には Elixir 用の API がなかったのです。が、 @Shintaro_Hosoai さんが Zenohex という Elixir 用の API を手掛けてくれてますので、それを使ってみることにしましょう。なお、おそらく Zenohex の発音は「ゼノヘックス」ではなく「ゼノ〜・イーエックス」だと思います。

なお Zenoh がどう素晴らしそうなのかは、やはり@Shintaro_Hosoai さんがお書きになってる Pub/Sub通信ライブラリZenohのススメ を御覧ください。

いごかしてみる

まずは zenohex の環境を作ります。いつものお作法通りです。

% mix new zenoh
% cd zenoh

mix.exs に1行追加します。

mix.exs
  defp deps do
    [
 +     {:zenohex, "~> 0.1.3"}
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end

そして依存関係を解決します。

% mix deps.get

これで準備ができました。

Pub/Sub 通信させてみる

2つのpublisherと2つのsubscriberを同じ key(トピック)で通信してみます1。以下では4つのターミナルを使います。全部同一のマシン上でいごかします。トピックは afo です。

  1. terminal 1: Pub側
  2. terminal 2: Pub側
  3. terminal 3: Sub側
  4. terminal 4: Sub側

全てのターミナルで iex を起動する

terminal 1
% iex -S mix
Erlang/OTP 26 [erts-14.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Interactive Elixir (1.16.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
terminal 2
%iex -S mix
Erlang/OTP 26 [erts-14.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Interactive Elixir (1.16.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
terminal 3
%iex -S mix 
Erlang/OTP 26 [erts-14.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Interactive Elixir (1.16.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
terminal 4
% iex -S mix
Erlang/OTP 26 [erts-14.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Interactive Elixir (1.16.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>

Publisher の準備をする

さきに Pub 側の準備をします。
まず Zenohex.open/0 関数で session を作ります。

terminal 1
iex(1)> session = Zenohex.open
#Reference<0.1263928079.4256563207.212580>

つぎに Publisher の宣言を Session.declare_publisher/2 で行います。

  • 第1引数: さきほどの session の #ref
  • 第2引数: トピック (key)

今回はトピック (key) を "afo" にします。

terminal 1
iex(2)> {:ok, publisher} = Session.declare_publisher(session, "afo")
{:ok, #Reference<0.1263928079.4256563201.214873>}

もうひとつの Publisher 用のターミナル2でも同じことをします。

terminal 2
iex(1)> session = Zenohex.open
#Reference<0.1869669285.1303773189.148236>
iex(2)> {:ok, publisher} = Session.declare_publisher(session, "afo")
{:ok, #Reference<0.1869669285.1303773187.149528>}

Subscriber の準備をする

つぎに Sub 側の準備をします。
まず Zenohex.open/0 関数で session を作ります。

terminal 3
iex(1)> session = Zenohex.open
#Reference<0.1665375593.2109341703.230733>

つぎに Subscriber の宣言を Session.declare_subscriber/3 で行います。

  • 第1引数: さきほどの session の #ref
  • 第2引数: トピック (key)
  • 第3引数: コールバック関数

先程の publisher の場合より引数が増えてることに注意です。

terminal 3
iex(2)> Session.declare_subscriber(session, "afo", fn m -> IO.inspect(m) end)
:ok

この宣言で、該当するトピック(key)で pub されたら、コールバック関数が呼ばれます。そのときのメッセージ(value)はコールバック関数の引数に渡されます。
今回は貰った値を IO.inspect/2 でそのままターミナルに出力します。

もうひとつの Subscriber 用のターミナル4でも同様のことをします。

terminal 4
iex(1)> session = Zenohex.open
#Reference<0.34013382.2646212610.123859>
iex(2)> Session.declare_subscriber(session, "afo", fn m -> IO.inspect(m) end)
:ok

通信してみる

では Pub/Sub 通信をしてみましょう。まず、ターミナル1で発信します。

terminal 1
iex(3)> Publisher.put(publisher, "foo")
:ok
terminal 3
"foo"
terminal 4
"foo"

Subscriber のあるターミナル3とターミナル4とが受け取って出力してます。

こんどはターミナル2から発信します。

terminal 2
iex(3)> Publisher.put(publisher, "bar")
:ok
terminal 3
"bar"
terminal 4
"bar"

こちらもそのまま出力されました。

まとめ

Zenoh の Elixir API である Zenohex を用いて Pub/Sub をしてみました。簡単に Pub/Sub できました。

今回は NAT越えやネットワーク間通信をするための Zenoh ルータを用いていません。また Zenoh 独自の機能である pull や get も使っていません。今後、試していきたいと思います。

さて、明日の #NervesJP Advent Calendar 2023 の記事は @mitsuhiro さんの「Giocci on Nerves たぶん。」です。お楽しみに!

参考文献

  1. 通常の Pub/Sub で、トピック・メッセージと呼ぶ通信の単位を、Zenoh ではちょっとDBっぽく keyvalue と読んでます。

10
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
2