ActionCable on Rails5.0

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

対象コミットは[こちら](https://github.com/MariMurotani/my1stRails/commit/c0b554d11802024891c11ce51f2e9af5a9c1bd10)
自分用のメモでもあるので[コミット一覧](https://github.com/MariMurotani/my1stRails/pull/7)もはります。


全体的な流れは、
ページを表示→ウェブソケットで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
```

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

```rb: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クライアントが接続します。

```rb:config/routes.rb
Rails.application.routes.draw do
   get 'rooms/show'
 
   # mount /cable as ActionCable consumer endpoint
   mount ActionCable.server => '/cable'
  end
```

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

```rb: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の作成

```js:app/assets/javascripts/cable.js
 //
 //= require action_cable
 //= require_self
 //= require_tree ./channels
  
 (function() {
   this.App || (this.App = {});
```

```js: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の作成
```html:app/views/messages/_message.html.erb
<div class="message">
   <p><%= message.content %></p>
</div>
```

```html: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