- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2022-02-08T05:38:37+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が書き換えられる。