目的
マッチングアプリを作成するにあたって、トークルームを実装したい。
ActionCableについてあとで見返して分かるようにメモ。
グループの作成までを目標にする。
参考にしたサイト
Rails 5の目玉機能「Action Cable」で双方向通信を実装(1)
https://codezine.jp/article/detail/10153
手順
1. railsアプリの作成
省略する。
注. 後ほどActionCable作成時にcoffeeスクリプトが作成され、その中でjqueryを用いる。
そのため、Gemfileに gem 'jquery-rails'
を追記。
2. controllerの作成
チャットの入力、表示のためのcontrollerとviewsを用意する。
bin/rails g controller talkRooms index
<div id="talk_rooms">
</div>
</br>
<form>
<label>
発言する: <input type="text" data-behavior="speak_talk_rooms">
</label>
</form>
#talk_room
の中には発言された内容が入る。
3. modelの作成
投稿者のIDと内容を保存するため以下のコマンドを実行する。
bin/rails g model talk_room user_id:integer message:text
4. channelの作成
ここからがActionCableの出番!。
rails g channel
でジェネレートする。
第一引数はチャネル名
第二引数は自動で追加したいメソッドを指定する。
rails g contoller
と似ていますね。
bin/rails g channel talk_room speak
ここではcontroller,modelと名前を合わせて第一引数にtalk_room
を、第二引数にはspeak
を指定。
4. クラインアント側(送信)
(略)
speak: (message) ->
@perform 'speak', message: message #引数にmessageを追加
$(document).on 'keypress', '[data-behavior~=speak_talk_rooms]', (event) ->
if event.keyCode is 13
App.talk_room.speak event.target.value
event.target.value = ""
event.preventDefault()
このcoffeeスクリプトはクライアント側から呼び出される。
@perform
のあとの'speak'
はchannels/talk_room_channel.rb
の中のspeak
メソッドを示している。
keypressイベントのApp.talk_room.speak
ではtalk_room.coffee
内のspeakメソッドを呼び出している
修正する点は、speakメソッドの引数にmessage: message
を追加する。
注. app/assets/javascripts/talk_rooms.coffee
と勘違いしやすいかも。
keypressイベントでは、'data-behavior~=speak_talk_rooms'
に対して、keyCode=13(returnキー)の入力を取得し、フォーム内の内容を取得している。
取得後はフォームの内容を空にして、送信を中断する。
5. サーバ側での処理
class TalkRoomChannel < ApplicationCable::Channel
def subscribed
# stream_from "some_channel"
stream_from 'talk_room_channel'
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def speak
ActionCable.server.broadcast 'talk_room_channel', message: data['message']
end
end
subscribed
メソッドでは、どこに配信するかを指定している。これをストリームといい、stream_from
で指定する。
またspeak
メソッドでは、第一引数talk_room_channel
に対してサーバ側から第二引数の発言メッセージを配信する。
先程クライアント側で引数に指定したmessage: message
はdata['message']
で取り出せる。
6. クライアント側(受信)
(略)
received: (data) ->
# Called when there's incoming data on the websocket for this channel
$('#talk_rooms').append '<div>' + data['message'] + '</div>'
(略)
クライアント側(coffeeスクリプト)でreceivedメソッドを用いる。
最初にtalkRooms/index.html.erb
に用意した#talk_rooms
タグ内にdata['message']
を追加する。