Catatsu Tech Blog


CatatsuはHASIGOです

Rails5で爆速チャットアプリを作ってみた


どうも僕(@nabeen)です。

Rails5では、コアを構成するライブラリにAction Cableが追加されました。これを使うと、Web Socketを使ったリアルタイムなチャットアプリケーションが簡単に作れるらしい、、!?

※本記事はWEB+DB PRESS Vol.93の内容を一部改変したものになります。

前準備

まずはローカルにプロジェクト用のディレクトリを掘る。

$ mkdir trailen
$ cd trailen

んでgit管理下にして、README.mdを追加しておきます。

$ git init
$ touch README.md
$ echo "trailen" >> README.md

.gitignoregiboで作るのがトレンドだと信じているので、giboを使って生成しようそうしよう。

$ touch .gitignore
$ gibo OSX Ruby Rails Vagrant JetBrains >> .gitignore

開発環境構築

僕はrails-dev-boxをベースにちょこっとカスタマイズして使いました。基本、cloneして来るだけで使えるのでここでは詳細は割愛。

後は簡単ですね。

$ vagrant up
$ vagrant ssh

Railsのインストール

グローバルにrailsをインストールします。

$ sudo gem install rails
$ rails -v
Rails 5.0.0.1

最新版キタ━━━━(゚∀゚)━━━━!!

新規アプリの作成

テストなし、DBをmysqlで作成します。完全に僕の好みです。テストはRspec使いたいんでね(この記事では書きません)。

$ rails new trailen -T -d mysql

DBは作ってくれないので、ここは手動で。

mysql> create database trailen_development;
Query OK, 1 row affected (0.00 sec)

ここまで来ればサーバー起動でデフォルト画面が表示されます(DBのパスワードとかはちゃんと設定してね)。rails5になってデフォルト画面変わっていることに少しの感動を覚える僕。

$ rails s -b 0.0.0.0 -p 8888

コントローラーの作成

長い前準備が終わり、ようやく本命のチャットアプリに着手します。ジェネレータでチャット表示用のコントローラーを作成します。

$ ./bin/rails g controller rooms show

モデルの作成

次は当然モデルですね。メッセージ保存用。

$ ./bin/rails g model message content:text
$ ./bin/rails db:migrate

ビューの作成

本体と、

<h1>Chat room</h1>

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

パーシャル。

<div class="message">
  <p><%= message.content%></p>
</div>

チャネルの作成

んで、これまたジェネレータでチャンネルを作っていきます。

$ ./bin/rails g channel room speak
Running via Spring preloader in process 11323
      create  app/channels/room_channel.rb
   identical  app/assets/javascripts/cable.js
      create  app/assets/javascripts/channels/room.coffee

app/channels/room_channel.rbapp/assets/javascripts/channels/room.coffeeが作成されました(ナニコレ)。前者がサーバーサイドの処理、後者がフロント側の処理を担当するっぽい。

んで、ここまでくればWebSocketのコネクションが貼れるはずだったんだけど、ここでエラーが発生します。どうやら許可されていないホストらしい。わざわざ許可せないかんのか。

Started GET "/cable" for 192.168.33.1 at 2016-09-27 12:40:45 +0000
Cannot render console from 192.168.33.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Started GET "/cable/" [WebSocket] for 192.168.33.1 at 2016-09-27 12:40:45 +0000
Request origin not allowed: http://192.168.33.33:8888
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for 192.168.33.1 at 2016-09-27 12:40:45 +0000

先人によると、設定を追加してあげないといけないようで、

参考:Action CableのREADMEを読んでみた!

僕の環境だと、以下の設定をconfig/environments/development.rbに追記してあげました。ここは人それぞれだと思うので、自信の環境に合うように設定してください。

config.action_cable.allowed_request_origins = ['http://localhost:8888']

追記して再起動したらOKになりました。うん、いいね順調順調。

Finished "/cable/" [WebSocket] for 10.0.2.2 at 2016-09-27 12:43:43 +0000
Started GET "/cable" for 10.0.2.2 at 2016-09-27 12:43:43 +0000
Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Started GET "/cable/" [WebSocket] for 10.0.2.2 at 2016-09-27 12:43:43 +0000
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
RoomChannel is transmitting the subscription confirmation

あとはもうガーッとコーディングしていけば完成!DBに突っ込んだりイベント発火させたりわちゃわちゃわちゃわちゃ必要だもんね。ガーッと書きましょう。ガーッと。

で、この時点のコードを見たい方はGithubに乗せていますので、そちらをご参照あれ(書く気力がなくなった)。 もちろん本番で運用する場合はもっと設定が必要ですが、とりあえずサクッと作れそうだなという感触は得られましたね。

おわりに

今回はサクッと作るところまでで終わったけど、最終的にはあれやこれやしてメインのWEBアプリのサブ機能的な位置づけでひっそり存在するくらいにはしていきたいという願望。

ぼくはれいるずとおともだちになるんだ!