#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が書き換えられる。