[Rails5]Action Cableを試してみる


[rails/actioncable](https://github.com/rails/actioncable)

Rails5にて実装予定のActionCableのalpha版が公開されたので、試してみました。

# Action Cableとは

RailsにWebSocketを組み込む機能で、クライアントサイドからサーバサイドまでフルスタックな機能が提供されるということです。

# 試してみる

サンプルアプリケーションが公開されていたので、まずはこちらを動かすことで内容を掴んでいこうと思います。

[rails/actioncable-examples](https://github.com/rails/actioncable-examples)

## サンプルアプリケーションのインストール

Rails5はRuby2.2.2以上でサポートされているので、rbenvなどでRubyのバージョンを2.2.2にしておきます。

```
# ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
```

次にサンプルアプリケーションをリポジトリからクローンしてきます。

```
# git clone https://github.com/rails/actioncable-examples.git
```

クローンが終わったらGemをインストールします。

```
# bundle install --path vendor/bundle
```

インストールされたGemを確認します。
Rails5.0.0.alphaとactioncable0.1.0がインストールされています。

```
# bundle list
Gems included by the bundle:
  * actioncable (0.1.0 849278d)
  * actionmailer (5.0.0.alpha c35c0c4)
  * actionpack (5.0.0.alpha c35c0c4)
  * actionview (5.0.0.alpha c35c0c4)
  * activejob (5.0.0.alpha c35c0c4)
  * activemodel (5.0.0.alpha c35c0c4)
  * activerecord (5.0.0.alpha c35c0c4)
  * activesupport (5.0.0.alpha c35c0c4)
  * arel (7.0.0.alpha 14df08d)
  * binding_of_caller (0.7.2)
  * builder (3.2.2)
  * bundler (1.10.5)
  * byebug (5.0.0)
  * celluloid (0.16.0)
  * coffee-rails (4.1.0 c05fb72)
  * coffee-script (2.4.1)
  * coffee-script-source (1.9.1.1)
  * columnize (0.9.0)
  * debug_inspector (0.0.2)
  * em-hiredis (0.3.0)
  * erubis (2.7.0)
  * eventmachine (1.0.7)
  * execjs (2.5.2)
  * faye-websocket (0.9.2)
  * globalid (0.3.5)
  * hiredis (0.5.2)
  * hitimes (1.2.2)
  * i18n (0.7.0)
  * jbuilder (2.3.1)
  * jquery-rails (4.0.4)
  * json (1.8.3)
  * loofah (2.0.2)
  * mail (2.6.3)
  * method_source (0.8.2)
  * mime-types (2.6.1)
  * mini_portile (0.6.2)
  * minitest (5.7.0)
  * multi_json (1.11.2)
  * nokogiri (1.6.6.2)
  * puma (2.11.3)
  * rack (1.6.4)
  * rack-test (0.6.3)
  * rails (5.0.0.alpha c35c0c4)
  * rails-deprecated_sanitizer (1.0.3)
  * rails-dom-testing (1.0.6)
  * rails-html-sanitizer (1.0.2)
  * railties (5.0.0.alpha c35c0c4)
  * rake (10.4.2)
  * redis (3.2.1)
  * sass (3.4.16)
  * sass-rails (5.0.3)
  * spring (1.3.6)
  * sprockets (3.2.0)
  * sprockets-rails (3.0.0.beta1 34ae184)
  * sqlite3 (1.3.10)
  * thor (0.19.1)
  * thread_safe (0.3.5)
  * tilt (1.4.1)
  * timers (4.0.1)
  * turbolinks (2.5.3)
  * tzinfo (1.2.2)
  * uglifier (2.7.1)
  * web-console (2.2.1 baafb8e)
  * websocket-driver (0.5.4)
  * websocket-extensions (0.1.2)
```

DBをマイグレーションします。

```
# rake db:migrate
== 20150711093646 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0014s
== 20150711093646 CreateUsers: migrated (0.0015s) =============================

== 20150711101414 CreateMessages: migrating ===================================
-- create_table(:messages)
   -> 0.0016s
== 20150711101414 CreateMessages: migrated (0.0017s) ==========================

== 20150711103112 CreateComments: migrating ===================================
-- create_table(:comments)
   -> 0.0026s
== 20150711103112 CreateComments: migrated (0.0026s) ==========================
```

起動してみます。

```
# rails s
=> Booting Puma
=> Rails 5.0.0.alpha application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma 2.11.3 starting...
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:3000
```

こんな画面が表示されました。

![Kobito.OONCCC.png](https://qiita-image-store.s3.amazonaws.com/0/32701/5236fc7a-28c2-67d6-01fe-30c7ce2c9acc.png "Kobito.OONCCC.png")

## サーバを起動する

次にサンプルのドキュメントにある通り、サーバを起動してみます。

`./bin/setup`を実行します。
先ほどbundle installとdb:migrateをやってしまったので特に何も起きません。

```
# ./bin/setup
== Installing dependencies ==
The Gemfile's dependencies are satisfied

== Preparing database ==
db/development.sqlite3 already exists
-- create_table("comments", {:force=>:cascade})
   -> 0.0629s
-- create_table("messages", {:force=>:cascade})
   -> 0.0044s
-- create_table("users", {:force=>:cascade})
   -> 0.0026s
-- initialize_schema_migrations_table()
   -> 0.0071s

== Removing old logs and tempfiles ==

== Restarting application server ==
```

`./bin/cable`を実行します。
ActionCableのプロセスが起動しました。

```
# ./bin/cable
Puma starting in single mode...
* Version 2.11.3 (ruby 2.2.2-p95), codename: Intrepid Squirrel
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:28080
Use Ctrl-C to stop
```

Railsサーバを起動します。

```
# rails s
=> Booting Puma
=> Rails 5.0.0.alpha application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma 2.11.3 starting...
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:3000
```

最後にRedisを起動します。
（Redisがインストールされていない場合は、brewなどでインストールしてください。）

```
# redis-server
[32807] 13 Jul 14:22:17.502 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
[32807] 13 Jul 14:22:17.504 * Max number of open files set to 10032
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 2.8.4 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 32807
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[32807] 13 Jul 14:22:17.512 # Server started, Redis version 2.8.4
[32807] 13 Jul 14:22:17.512 * The server is now ready to accept connections on port 6379
```

## 動作確認

ページにアクセスしてみます。
先ほどは表示されていなかったリンクが表示されました。

Cookieを共有しないブラウザを2つ起動し、2つのブラウザでそれぞれ別のユーザでログイン（リンクをクリック）します。

![Kobito.aoQhlS.png](https://qiita-image-store.s3.amazonaws.com/0/32701/4cd5ce51-9c13-cafb-4b4f-84f5ef232496.png "Kobito.aoQhlS.png")

ログインしたユーザ名が表示されています。

![Kobito.eUA2Zy.png](https://qiita-image-store.s3.amazonaws.com/0/32701/1947c898-2cbe-ef68-7f47-cb02abaf92bd.png "Kobito.eUA2Zy.png")

Messages（チャットのスレッド）を選びます。2つのユーザで同じ部屋に入ります。

![Kobito.RMhr3h.png](https://qiita-image-store.s3.amazonaws.com/0/32701/781d2f7a-e5ad-e8c2-7584-b7d46ccd65a3.png "Kobito.RMhr3h.png")

1つのブラウザからメッセージをポストすると、もうひとつのブラウザにリアルタイムでメッセージが表示されました！

![Kobito.qcgdlT.png](https://qiita-image-store.s3.amazonaws.com/0/32701/2b2566d1-69a6-9908-3aca-72e6eac79a91.png "Kobito.qcgdlT.png")

![Kobito.gTdHoz.png](https://qiita-image-store.s3.amazonaws.com/0/32701/977441dc-61ac-17b6-313b-b1673ed8b2ae.png "Kobito.gTdHoz.png")

# まとめ

まだコードは読んでいないのでどれだけ簡単に実装できるのかは分かりませんが、WebSocketのフレームワークが提供されたことでRailsでもシングルページアプリケーションを作りやすくなるのではないでしょうか。

次は実装コードを読んでいこうと思います。