Aqutras Members' Blog

株式会社アキュトラスのメンバーが、技術情報などを楽しく書いています。

websocket-railsをproduction環境で運用する

今回のAqutrasブログの執筆担当はvitaminです!書き始めで既に遅刻ですごめんなさい。

先日、私用でwebsocket_railsを利用したRailsアプリを開発したのですが、デプロイに予想以上に躓いたので記事にしたいと思います。

websocket-railsとは

WebSocketsとは、サーバ・クライアント間で、一方向ではなく双方向で情報をやり取りするための規格です。
これを利用することで、チャットアプリのようなリアルタイムに情報をやり取りすることができるアプリを開発したりすることが出来ます。
websocket-railsとは、websocketをrailsで利用するためのgemです。

github.com

websocket-railsの使い方

使い方自体は、web上で様々な方々が公開しているので、困ることは無いと思います。
基本的な流れは、以下のとおりです。

  • Gemfileに記述
  • config/events.rb でルーティングを決定
  • コントローラを作成
  • View側で コネクションを確立し、待機するイベント、送信するイベントを定義

production環境でのwebsocket

上記のやり方は、railsのルーティングに /websocket を追加し、そこへのアクセスをwebsocketが処理しています。
この状態で、unicornを利用してrailsアプリをproductionでデプロイしてみます。
すると以下の様なエラーが発生し、websocket通信ができませんでした。

'websocket connection to ws:/localhost:3000/websocket' failed. Error during websocket handshake. Unexpected response code: 500.

railsのデプロイには、unicornを利用することが多いと思います。しかし、ここ によるとどうやらunicornを利用する場合、websocket-railsはstand alone mode で起動しなければ通信が出来ないようでした。
そのため、公式に書いてある通りに設定をし、起動します。

config/initializers/websocket_rails.rb

WebsocketRails.setup do |config|
  config.standalone = true
  config.standalone_port = 3001
end

$ bundle exec rake websocket_rails:start_server

これでアクセスすると、エラーが発生しなくなりました。
しかし、イベントをトリガーしても応答が返ってこない。。。
websocketのログを見てみると、以下の様なエラーが発生していました。

Redis::CannotConnectError: Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)

どうやら、stand alone modeではredisを利用しているようなので、redisをインストールします。

$ rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ yum --enablerepo=epel -y install redis
$ /etc/init.d/redis start

redis-cli でコマンドラインが立ち上がれば完了です。
しかし、これで再起動してもエラーが直りません。
websocket-railsのissueを漁ってみたところ、全く同じ状態の人がいました。
Redis error when sending two different messages · Issue #313 · websocket-rails/websocket-rails · GitHub

これによると、バグだから修正した gem 'websocket-rails', github: 'moaa/websocket-rails', branch: 'sync_fixes' こっちを使えとのことでした。
Gemfileの記述を変更すると、無事に通信することができました。

おわりに

今回は、ずっとやってみたかったリアルタイム通信のwebページを作成することが出来ました。
websocketはいろいろ躓くことが多いようなので、誰かの助けになれば幸いです。
今度は、websocketを使った複数人用ゲームとか作ってみようかなーと思います。