Phoenixアプリでphoenix_pubsubを用いてメッセージを出版・購読するパターンがよく見られます。
実は、phoenix_pubsubはPhoenixアプリ以外でも利用することができ、どんなElixirプロジェクトからでも同様のメッセージのやり取りをすることができます。
これからElixirを始める方にはこのサイトがおすすめです。
Elixirとコミュニティの雰囲気をゆるく味わいたい方は「先端ピアちゃん」さんの動画が超オススメです。
実験:一つのIEx上でphoenix_pubsub
対話ElixirシェルIExで試してみます。 ターミナルを開き、IExを起動します。
iex
phoenix_pubsubをインストールします。
iex> Mix.install([{:phoenix_pubsub, "~> 2.0"}])
Phoenix.PubSub.Supervisorを起動します。
通常はElixirプロジェクトのSupervisorの子プロセスとしてPhoenix.PubSub.Supervisorを起動することが多いと思いますが、ここでは手動で立ち上げます。
iex> Phoenix.PubSub.Supervisor.start_link(name: :my_pubsub)
余談ですがPhoenix.PubSub.SupervisorのソースコードはIEx.Helpers.open/1コマンドで開くことができます。
iex> open Phoenix.PubSub.Supervisor
話題を決めます。
iex> topic = "闘魂Elixir"
話題を購読します。
iex> Phoenix.PubSub.subscribe(:my_pubsub, topic)
話題に対してメッセージを出版します。
iex> Phoenix.PubSub.broadcast(:my_pubsub, topic, "元氣があればなんでもできる!")
郵便受けを確認します。
iex> flush
"元氣があればなんでもできる!"
:ok
ノードは任意の話題を購読するとその話題に対して出版されたメッセージを受け取ることができます。
![]()
![]()
![]()
ただ自分で自分で出版したメッセージを自分で購読しても面白くないので、ノードを2つ(hogeノードとpiyoノード)立ち上げて同じことをやってみます。ノードは別々のPCでもOKです。
hogeノードがある話題を購読し、piyoノードが同じ話題に対してメッセージを出版したら、それがのhogeノード郵便受けに届くはずです。
実験:二つのノードでphoenix_pubsub 1
hogeノードを立ち上げます。
iex --sname hoge@localhost --cookie awesome_cookie
別のシェルでpiyoノードを立ち上げます。
iex --sname piyo@localhost --cookie awesome_cookie
両方のノードでphoenix_pubsubをインストールして(同じ名前の)Phoenix.PubSub.Supervisorを起動します。
iex(hoge@localhost)> Mix.install([{:phoenix_pubsub, "~> 2.0"}])
iex(hoge@localhost)> Phoenix.PubSub.Supervisor.start_link(name: :my_pubsub)
iex(piyo@localhost)> Mix.install([{:phoenix_pubsub, "~> 2.0"}])
iex(piyo@localhost)> Phoenix.PubSub.Supervisor.start_link(name: :my_pubsub)
hogeノードからpiyoノードに接続します。
iex(hoge@localhost)> Node.ping(:"piyo@localhost")
:pong
iex(hoge@localhost)> Node.list
[:piyo@localhost]
hogeノードで"闘魂Elixir"という話題を購読します。
iex(hoge@localhost)> Phoenix.PubSub.subscribe(:my_pubsub, "闘魂Elixir")
:ok
piyoノードで"闘魂Elixir"という話題に対してメッセージを出版します。
iex(piyo@localhost)> Phoenix.PubSub.broadcast(:my_pubsub, "闘魂Elixir", "元氣があればなんでもできる!")
hogeノードの郵便受けを確認。
iex(hoge@localhost)> flush
"元氣があればなんでもできる!"
:ok
piyoノードが出版したメッセージがhogeノードの郵便受けに届きました。
![]()
![]()
![]()
出版-購読型モデルではノードからノードに直接メッセージを送るのではなく、ある話題に興味のある購読者が一斉にメッセージを受け取ることができます。
実験:二つのノードでphoenix_pubsub 2
同じことをもっと簡単にできればと思い、コードをパッケージ化しました。
iex
iex(hoge@localhost)> Mix.install([{:kantan_cluster, "~> 0.5.0"}])
iex(hoge@localhost)> KantanCluster.start_node(sname: :hoge, cookie: :awesome_cookie)
iex(hoge@localhost)> KantanCluster.subscribe("闘魂Elixir")
iex
iex(piyo@localhost) Mix.install([{:kantan_cluster, "~> 0.5.0"}])
iex(piyo@localhost) KantanCluster.start_node(sname: :piyo, cookie: :awesome_cookie)
iex(piyo@localhost) KantanCluster.broadcast("闘魂Elixir", "元氣があればなんでもできる!")
iex(hoge@localhost)> flush
"元氣があればなんでもできる!"
:ok
簡単に出版-購読型モデルを楽しめました!
![]()
![]()
![]()
:erpc.call/4で遠隔手続き呼出し
それに対して、直接特定のノードにメッセージを送りたいときは:erpc.call/4を用いた遠隔手続き呼出しが便利そうです。
phoenix_pubsubはErlangのpgモジュールを使って実装されているようです。詳しいことは知りません。
ご参考までに