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モジュールを使って実装されているようです。詳しいことは知りません。
ご参考までに