はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー14日目です。
Turbo Stream(ActionCable)を使ったリアルタイム通信について学習したので、引き続きまとめます。
こちらの記事ではリアルタイム通信を実現する仕組みとしてWebsocketを紹介し、Action CableがWebsocketを扱うための機構であることを説明しました。
本記事では、もう少し具体的にリアルタイム通信を行うイメージを説明したあと、実際のコードでどのように書くのかを紹介します。
Railsのリアルタイム通信の流れ
1.サーバ側でリアルタイム通信の準備をする
リアルタイム通信をするためには、サーバ側にてあらかじめ準備が必要です。どんな情報を送るのかなどを決めておきます。これを、チャンネル(チャネル?)と呼びます。RailsではActionCableにてChannelというクラスが用意されており、Railsアプリ内にこのクラスを継承したクラスを用意することで、準備ができます。
2.クライアントがサーバにリアルタイム通信を要求する
リアルタイム通信の流れとしてまずは、クライアントからサーバに「リアルタイム通信したいです!」と伝える必要がありますよね。
どうすれば良いかというと、Rails単体でアプリを作る場合はTurboライブラリがよしなにやってくれます。
Action Cableではクライアント側用にJavaScriptのライブラリも用意しており、それを活用するヘルパーメソッドを書くことで指定されたストリームからのデータの更新をリアルタイムで受け取るための準備を設定できます。これを、サブスクライブすると言います。
3.サーバが情報をクライアントにプッシュする
あとは、クライアント側に更新が必要な場合にサーバから通信を行います。ただしこれができるのは、「リアルタイム通信したい」旨を伝えたクライアントに向けてのみです。例えばあるユーザーがupdateアクションへリクエストし、それによりあるページに更新が必要となった場合、サブスクライブしているクライアント全てに対して(つまり、特定のページを「今まさに」開いているクライアントに対して)サーバから情報が送信されます。結果として、何も操作をしなくても通知が届く、メッセージが更新されるということができるわけですね。すごい!
この時情報を送信することを「ブロードキャスト」と呼びます。Turbo Streamsを使ったブロードキャストの場合、○○.turbo_stream.erbというファイルを元にレンダリングされたHTMLがレスポンスされます。
実際のコード例
1.サーバ側でリアルタイム通信の準備をする
実は、Turbo Streamをブロードキャストする場合はチャンネルを用意する必要はありません。
代わりにブロードキャストするための○○.turbo_stream.erbを用意する必要があります。こちらはこのあと紹介します。
2.クライアントがサーバにリアルタイム通信を要求する
例えば、とあるページでクライアントのページをサーバから情報を送る形で更新したい場合、ページの先頭に以下のように書いておきます。
<%= turbo_stream_from "cats" %>
このようにすることで、このページを開いている間はサーバに「リアルタイム通信したいです!」と伝えることになります。
サーバは、ページからのリクエストを受けてチャンネルをサブスクライブさせます。
3.サーバが情報をクライアントにプッシュする
サーバが情報をクライアントに送るためには、アクション内に情報を送るメソッドを書いておく必要があります。以下のように書きます。
def update
if @cat.update(cat_params)
@cat.broadcast_replace_to("cats")
flash.now.notice = "ねこを更新しました。"
else
render :edit, status: :unprocessable_entity
この@cat.broadcast_replace_to
メソッドが動くと、そのアクションのリクエスト元のクライアントだけではなくcatsをサブスクライブしているクライアント全てにサーバから情報が送信されます。送信されるのは、今回の例の場合cats/update.turbo_stream.erb
ですね。
終わりに
Turbo Streamsを使うと、Rails側にChannelを用意しなくてもリアルタイム通信ができることがわかりました。
疑問点
Channelと併用することがあるのか、Action Cableの細かな仕様やオプション、できることなどがまだわからないので、調べてみます。