1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

最新のRuby on Railsに一人で迫ってみる挑戦Advent Calendar 2023

Day 14

概念から理解するTurbo Streamsを使ったリアルタイム通信

Last updated at Posted at 2023-12-16

はじめに

本記事は錆びかけた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.クライアントがサーバにリアルタイム通信を要求する

例えば、とあるページでクライアントのページをサーバから情報を送る形で更新したい場合、ページの先頭に以下のように書いておきます。

index.html.erb
<%= turbo_stream_from "cats" %>

このようにすることで、このページを開いている間はサーバに「リアルタイム通信したいです!」と伝えることになります。
サーバは、ページからのリクエストを受けてチャンネルをサブスクライブさせます。

3.サーバが情報をクライアントにプッシュする

サーバが情報をクライアントに送るためには、アクション内に情報を送るメソッドを書いておく必要があります。以下のように書きます。

○○_controller.rb
  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の細かな仕様やオプション、できることなどがまだわからないので、調べてみます。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?