Rails 5.0.0-beta1 が December 18, 2015 にリリースされたようです。
公式ブログを爆速で翻訳してくださった方がいるので、そちらも貼っておきます。
WebSocket を扱える Action Cable に興味があったので、早速 Rails 5.0.0-beta1 を入れて、ほぼ写経で超簡易チャットを作ってみました。
Rails 5.0.0-beta1 をインストール
以下のコマンドでインストールできます。
$ gem install rails --pre
Ruby は 2.2.2 以上が必要らしいです。
Redis をインストール
Action Cable では Redis を使用するらしいので、そちらもインストールしておきます。
$ brew install redis
インストールしたらredis-server
と叩いて起動しておきます。
チャット画面の作成
ネットの海をさまよってたらやりたいことを Rails 4 と ActionCable を使ってほぼまんまやってるくださってる記事を見つけました。
ありがたく写経に励みます。
config/routes.rb
Rails.application.routes.draw do resources :sessions, only: %i(new create) resources :messages, only: %i(index create) end
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController def create cookies.signed[:username] = params[:session][:username] redirect_to messages_path end end
app/views/sessions/new.html.slim
= form_for :session, url: sessions_path do |f| = f.label :username, "Enter a username" br = f.text_field :username br = f.submit "Start chatting"
app/controllers/messages_controller.rb
class MessagesController < ApplicationController def create head :ok end end
app/views/messages/index.html.slim
| Signed in as @ = cookies.signed[:username] br br #messages br br = form_for :message, url: messages_path, remote: true, id: "messages-form" do |f| = f.label :body, "Enter a message:" br = f.text_field :body br = f.submit "Send message"
erb ファイルは写経する気が起きなかったので、slim に書きなおしました。
これで画面が完成です。次は Action Cable の設定をしていきます。
Action Cable の有効化
先ほど紹介した記事中ではcable/config.ru
を作成してbundle exec puma -p 28080 cable/config.ru
を実行することでスタンドアローンで Cable サーバーを立ち上げていましたが、Rails 5.0.0-beta1 では デフォルト開発サーバーが Webrick から Puma に変更されているため、同一プロセス上で Action Cable が実行できます。
せっかくなので、bin/rails server
と起動するだけで Action Cable が使えるように設定したいと思います。
config/routes.rb
routes ファイルに以下のルーティングを追加します。
Rails.application.routes.draw do match "/websocket", to: ActionCable.server, via: %i(get post) end
app/assets/javascripts/cable.coffee
次に、cable.coffee ファイルで Websocket サーバを指定します。
@App ||= {} App.cable = ActionCable.createConsumer("/websocket")
Rails App と同一サーバで Action Cable を起動するため、上記のような記述になります。
開発サーバの設定がデフォルトであればws://localhost:3000/websocket
に対してコネクションを要求するようになります。
チャット用 Channel の追加
Consumer に Subscribe させる Channel を追加します。
app/channels/messages_channel.rb
参考サイトに従い MessagesChannel を作成しました。
class MessagesChannel < ApplicationCable::Channel def subscribed stream_from "messages" end end
チャットメッセージの Broadcasting
チャットメッセージが投稿された際に Channel に Broadcast するように設定します。
app/controllers/messages_controller.rb
class MessagesController < ApplicationController def create ActionCable.server.broadcast "messages", message: params[:message][:body], username: cookies.signed[:username] head :ok end end
Channel の Subscribe
Consumer に MessagesChannel を Subscribe させます。
app/assets/javascripts/channels/messages.coffee
App.messages = App.cable.subscriptions.create 'MessagesChannel', received: (data) -> $('#messages').append @renderMessage(data) renderMessage: (data) -> "<p><b>[#{data.username}]:</b> #{data.message}></p>"
開発サーバの起動
開発サーバをbin/rails server
で起動するとあら不思議、WebSocket を利用したリアルタイムチャットの完成です!
感想
あっという間にリアルタイムチャットが完成しました。 サーバープッシュを初めて実装したので、ほぼ写経だったとはいえ動いた時は感動しました。
今回は認証は不要だったので Connection Identifier については一切設定していませんが、こちらを設定すればコネクションの貼り直しなども簡単に行えそうです。
フロントエンドも含めて Rails のレールに乗って開発するなら、Action Cable を使えばかなり効率的に WebSocket を利用できるような気がします。
まとめ
おおまかに、
- Action Cable を有効化する
- Channel を作成する
- Channel に対する処理を実装する (Server/Client)
と言った手順で Action Cable を使用できました。
また、作成したリポジトリは Github に置いてあります。
余談
最初読み間違えてて The Haskell Cabal の親戚か何かかと思ってました。
今だに脳内で「Cabal」と読んでしまう。