#author("2022-02-21T04:00:42+00:00","default:src128","src128")
#author("2022-02-21T04:04:30+00:00","default:src128","src128")
&tag(Rails/ActionCable);
*目次 [#iaefa929]
#contents
*関連ページ [#k2096123]
*参考情報 [#mf729c2b]
-[[【Rails 6.0】Action Cable を解説しながらプログレスバーを実装する - Qiita:https://qiita.com/MONAKA0721/items/303b76fa8624cb00179b]]

*基本的情報 [#k1e9a590]
-サーバーから非同期にメッセージを送信できる。
-長い時間処理中にブラウザにメッセージを送信したり、プログレスバーを表示することができる。
-ただしproduction環境ではredisが必要(もしくはpostgresql)。
-Passengerの場合、Passenger+Apacheはだめで、Passenger+Ngixが必要。
-その他pumaとかだと大丈夫?


*簡単なサンプル [#a450b8de]

-パーフェクトRuby on Railsのp260あたりを参考に。
-入力した文字列が全てのブラウザに反映されるチャットルームのサンプル。

**手順 [#o872698e]
-メッセージを表示する基礎部分は省略。

***ファイルの生成 [#v46d8605]
-ジェネレータでAction Cable用のファイルを作る
 bin/rails g channel room speak
-app/channels/room_channel.rbがサーバーサイドの処理を、app/javascript/channels/rooms_channel.jsがそれぞれサーバー側、
クライアント側の処理を受けもつ。

***サーバーサイドのコードを実装 [#w221abce]
-room_channel.rbの実装。
#pre{{
class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    message = Message.create(content: data["message"])
    ActionCable.server.broadcast("room_channel", {message: render_message(message)})
  end

  def render_message(message)
    ApplicationController.render(partial: "messages/message", locals: {message: message})
  end
end
}}
-_message.html.erb
#pre{{
<div class="message">
  <p><%= message.content %></p>
</div>
}}
-show.html.erb
#pre{{
<h1>Chat room</h1>

<div id="messages">
  <%= render @messages %>
</div>

<form>
  <label>Say something:</label><br>
  <input type="text" data-behavior="room_speaker">
</for
}}

***クライアントサイドのコードを実装 [#s133e5a3]
-room_channel.js
#pre{{
import consumer from "./consumer"

consumer.subscriptions.create("RoomChannel", {
  connected() {
    document.querySelector('input[data-behavior="room_speaker"]').addEventListener('keypress', (event) => {
      if (event.key == 'Enter') {
        this.speak(event.target.value);
        event.target.value = '';
        return event.preventDefault();
      }
    });
  },

  disconnected() {
  },

  received(data) {
    const element = document.querySelector("#messages");
    element.insertAdjacentHTML('beforeend', data['message']);
  },

  speak: function(message) {
    return this.perform('speak', {message: message});
  }
});

}}

**説明 [#w8ec0b1e]
-入力ボックスに文字列に入力して「Enter」を押す。
-jsのspeak=>room_channel.rbのspeak。以下のメソッドでメッセージがブロードキャスト。
 ActionCable.server.broadcast("room_channel", {message: render_message(message)}) 
-jsのreceivedにデータが送られてきて(renderによって生成されたHTMLコード)、表示されているHTMLが書き換えられる。


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS