Phoenix + Reactでチャットアプリを作ろう(Part 3)

Phoenixを使ったMessageのWebsocket channel作成

Ichizo Umehara
5 min readMar 10, 2020

アプリ概要はPhoenix + Reactでチャットアプリを作ろう(Intro)参照。

ここまでのコードはP2_4_NEW_GROUP_PAGE参照。

本章ではPart 2で作成したGroup詳細画面からアクセスするWebsocketのChannelを構築する。

作業項目は以下の通り。

  • Messageモデルにusernameを追加
  • GroupChannelを作成

Messageモデルにusernameを追加

メッセージを表示する時に投稿したユーザ名も表示したいので、Messageモデルにusernameを追加しよう。(今回はユーザー認証・認可などを考慮せずにシンプルにMessageモデルへの変更で進めることとする。)

テストでMessageが初期化されている部分でusernameが含まれるように修正しよう。

/test/chatter_web/controllers/group_controller_test.exs
/test/chatter/chat_test.exs

テストが失敗するので、実装をしよう。

まずはDBから。

mix ecto.gen.migration alter_messages_add_username_column

生成されたMigrationファイルに新しいコラム名を追記して、

/priv/repo/migrations/2020xxxxxxxxxx_alter_messages_add_username_column.exs
mix ecto.migrate

テーブルにコラムが追加される。

追加されたコラムをSchemaにも定義して、

JSONにも追加すれば、

テストが全部通るはず。

GroupChannelを作成

Channelもphx.genで自動生成できる。

mix phx.gen.channel Group

作成されたgroup_channel_testを修正しよう。

/test/chatter_web/channels/group_channel_test.exs
  • Groupが存在しないとMessageを作成できないので、まずはGroupを作成して、
  • Websocketにデフォルトの“shout”イベントとMessageのオブジェクトを送る。
  • その結果、新しく作成されたMessageが同チャンネルに接続している全クライアントにブロードキャストされる。

Messageのバリデーション(group_id等の必須項目が含まれている)と新規作成(作成によりMessageIdがアサインされている)が確認できる。

実装は簡単だ。

/lib/chatter_web/channels/user_socket.ex

全てのgroupのchannelをGroupChannelに連携して、

/lib/chatter_web/channels/group_channel.ex

“shout”を処理するhandle_in/3の関数でChat.create_messageを呼び出すように修正。成功した場合は作成されたmessageをJSONに変換してブロードキャストする。JSON変換のロジックはViewの中で定義した。

/lib/chatter_web/views/message_view.ex

これでAPI側の改修は完成。

あとは、Webクライアントからgroup_idを使ってGroupのChannelに接続すれば、新しいMessage作成のShoutを遅れるし、他のクライアントの作ったMessageをブロードキャストで受け取ることもできる。

ここまでのコードはP3_GROUP_CHANNEL参照。

--

--