LoginSignup
6
6

More than 5 years have passed since last update.

ActionCable on Rails5.0

Last updated at Posted at 2016-08-19

こちらの記事を参考にActionCableでシンプルにSocket通信を利用してチャットができるようになるまでを実装したいと思います。
もともとあった他のアプリにもwebsocketで通信するスクリプトが入ってしまって、表示のパフォーマンスに影響があったので既存に組み込みよりも、新規にプロジェクトを作成する事をおすすめします。

対象コミットはこちら
自分用のメモでもあるのでコミット一覧もはります。

全体的な流れは、
ページを表示→ウェブソケットでJSからサーバーに接続
→ブラウザからデータを送信
→サーバー側で受け取りRedisに格納
→格納したデータをBroadcast
→サイドブラウザで受け取り表示する

1. Redisのインストールと起動

とりあえずインストールして起動しておきます。

wget http://download.redis.io/releases/redis-3.2.3.tar.gz
tar -xzvf redis-3.2.3.tar.gz
cd redis-3.2.3
make
make install
/usr/local/bin/redis-server

2.コントローラー、モデル、チャンネルを作成

全てコマンドラインで作成します。
1) コントローラー

rails g controller rooms show

2) モデル

rails g model message content:text
rails db:migrate

3) チャンネル

rails g channel room speak

3. .rbの編集

こちらはActionCableでSubscribeするチャンネルのコードです。

app/channels/room_channel.rb
 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.create! content: data['message']
     ActionCable.server.broadcast 'room_channel', message: data['message']
   end
 end

こちらは通常のコントローラーでモデルからデータを取り出して表示しているだけです。

app/controllers/rooms_controller.rb
class RoomsController < ApplicationController
   def show
       @messages = Message.all
   end
 end

ルーターの設定です。mount ActionCable.server => '/cable'というのがポイントで、今後ws://192.168.10.5:28080/cableというエンドポイントに向かってJSクライアントが接続します。

config/routes.rb
Rails.application.routes.draw do
   get 'rooms/show'

   # mount /cable as ActionCable consumer endpoint
   mount ActionCable.server => '/cable'
  end

下記の設定はVirtualBoxに立てたローカルサーバーで動かしているので必要でした。

config/environments/development.rb
# allow from all to websocket
ActionCable.server.config.disable_request_forgery_protection = true

# allow form only internal network
config.web_console.whitelisted_ips = '192.168.0.10/26'

4. JavaScriptの作成

app/assets/javascripts/cable.js
 //
 //= require action_cable
 //= require_self
 //= require_tree ./channels

 (function() {
   this.App || (this.App = {});
app/assets/javascripts/channels/room.js
(function() {
   App.room = App.cable.subscriptions.create("RoomChannel", {
     connected: function() {
       return console.log('connected------');
     },
     disconnected: function() {
       return console.log('disconnectd------');
     },
     received: function(data) {
       alert('message!');
       $('#messages').append(data['message']);
       return console.log('received------');
     },
     speak: function(data) {
       this.perform('speak',{message: data});
     }
   });

 }).call(this);

 //  start after document is ready
 $(document).ready(function(){
     $("input").keypress(function(event){
       if ( event.which == 13 ) {
          event.preventDefault();
          App.room.speak(event.target.value);
       }
     });
 });

5. HTMLの作成

app/views/messages/_message.html.erb
<div class="message">
   <p><%= message.content %></p>
</div>
app/views/rooms/show.html.erb
<h1>Chat room</h1>

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

 <form>
   <label>Say something:</label><br>
   <input type="text" data-behavior="room_speaker" style="background-color:silver">
 </form>

6. 起動

上記のコードはRailsServerで動く設定になっています。
192.168.10.5でVirtualMachineを動かしているので下記のコマンドで動かします。

rails server -b 192.168.10.5

6
6
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
6
6