IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

Ruby & Rails

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes 

第34回 あのGemは今 WebSocket編 (松永紘) 2018年3月

 前回の"引き"で過去回の回収も含め、WebSocket関連のGemとRails5から導入された「ActionCable」を取り上げると書きました。
 しかしながらWebSocket関連のGemに関する部分が思いのほか長くなってしまったので、今回は「あのGemは今 WebSocket編」と題してお送りしたいと思います(*1)。
 動作環境は執筆時時点での最新である、Ruby2.5.0、Rails5.1.5です。

第13回EM-WebSocket(2014年4月)

 バージョン: 0.5.0 -> 0.5.1

 Rubyで実装されたWebSocketライブラリでしたね。
 執筆した時からマイナーバージョンアップ1回のみでその時期も2014年4月23日(*2)と、活発にアップデートされている様子は伺えませんが、一応今でも動くようです。

fig01

 なお紹介した時にはWindows環境でインストールが失敗するという不具合がありましたが、0.5.1のアップデートとの際に依存するhttp_parser.rbのバージョンを0.6.0にしたことで解消したようです(*3)。

第14回Websocket-Rails(2014年5月)

 バージョン: 0.7.0 -> 0.7.0

 Railsアプリケーション上でWebSocketを簡単に使えるライブラリ、でしたがバージョンが一切上がっていないことからも分かる通り、現在最新の環境で動かそうとすると一筋縄ではいきません。
 手っ取り早く動かすためには以下の手順を踏む必要があります。

  1. faye-websocketのバージョンを0.10.0に固定
  2. アプリケーションサーバをPumaから変更
1. faye-websocketのバージョンを0.10.0に固定

 Websocket-Railsはfaye-websocketに依存していますが、このfaye-websocketのバージョンが0.10.0よりも新しいものあると上手く動いてくれません(*4)。そのためGemfileに以下の記述をする必要があります(*5)。

gem 'faye-websocket', '0.10.0'
2. アプリケーションサーバをPumaから変更

 Rails5からPumaがデフォルトのアプリケーションサーバとなりましたが、PumaのようなEventMachineベースでないサーバの場合はWebsocket-RailsをStandaloneモードで動かす必要があります。
 後述しますがこの手順はまたハマりどころが存在するので、手早く動かすのであれば起動するアプリケーションサーバを変えてしまいましょう。
 以下のようにRailsを起動するとThinが立ち上がります。(*6)

$ rails s -b 0.0.0.0 Thin

 ThinはEventMachineベースのサーバであるため、特に設定を変えることなく動くことが確認できるかと思います。

 もしThinではなく、EventMachineベースでないPumaのようなアプリケーションサーバを使いたい場合は、さらに以下の手順を踏む必要があります。

  1. Redisのインストール
  2. 依存Gemのバージョン指定
  3. Websocket-RailsをStandaloneモードで起動するように設定
  4. JavaScriptのWebSocket接続先ポートを変更
3. Redisのインストール

 Websocket-RailsをStandaloneモードで動かす場合、Redisをインストールする必要があります。ここではRedisそのもののインストール手順の詳細は割愛しますが、例えばUbuntuであれば以下のようなコマンドでインストールできるでしょう。

$ sudo apt-get install redis-server
4. 依存Gemのバージョン指定

 Gemfileに以下の追記を行い、「bundle update」を実行します。

gem 'eventmachine', '1.0.9'
gem 'redis', '~> 3.3'
gem 'redis-objects', '1.3.1'

 本来であればWebsocket-Railsインストール時に必要なライブラリが全てインストールされるのですが、faye-websocketの時のようにバージョンの問題によりそのままでは上手く動きません。そのためいくつかの依存ライブラリに対してバージョンを指定する必要があります。
 「eventmachine」はWebsocket-Railsの依存ライブラリですが、執筆時点の最新バージョンである1.2.5でStandaloneモードを起動しようとするとSegmentationのエラーが発生します(*7)(*8)。バージョンが1.0.9では起きないようなのでそのバージョンを指定します。
 「redis」関連のGemはその名の通りRailsからRedisを扱うためのものです。このうち「redis」は執筆時点で最新が4.0.1となっていますが、このバージョではWebsocket-Railsからの呼び出し時に以下の例外が発生します。

undefined method `connect' for Redis:Class (NoMethodError)

 Redis 4.xからインタフェースが変わったことによる例外のようで、3.xではconnectメソッドが存在するためそちらを使うように指定します。
 また「redis-objects」のバージョンが1.4以降である場合、redis4.0以降に依存するため「bundle update」が失敗してしまいます。そのため1.3.1を使うよう明示的に指定します。

5. Websocket-RailsをStandaloneモードで起動するように設定

 続いてWebsocket-RailsをStandaloneモードで起動するように設定を行います。
 Websocket-Railsを使う際、必要なファイルを「rails g websocket_rails:install」コマンドで生成しているかと思います。この時に生成された「config/initializers/websocket_rails.rb」を以下のように修正します(*9)。

WebsocketRails.setupdo |config|
  config.standalone = true
end

 また、以下のコマンドを実行しWebsocketサーバを起動しておきます。

$ rake websocket_rails:start_server
6. JavaScriptのWebSocket接続先ポートを変更

 WebsocketサーバをRailsサーバとは別に起動するため、接続先のポートを変更しなければなりません。「config/initializers/websocket_rails.rb」で特に設定をしない場合、3001でWebsocketリクエストをListenするのでJavaScriptからのリクエストも3001となるようにします。

 「app/views/chat/index.html.erb」10行目あたりの記述を、以下のように変更します。

<script>
  // var ws_rails = new WebSocketRails("localhost:3000/websocket");
  var ws_rails = new WebSocketRails("localhost:3001/websocket");

 ここまでの手順を終えたら「rails s」コマンドでRailsサーバを起動し、ページを表示してみましょう。ここまでしてWebsocket-Railsを使うのかという感じではありますが、以前のチャットアプリケーションが動作していることを確認できるかと思います(*10)。

fig02

まとめ

 ここまでRubyやRailsからWebSocketを扱うライブラリを見てきました。どちらも開発は止まっている状態で、今後のRubyやRailsのバージョンアップに追随していくのはなかなか厳しそうな状況です。
 ただ、Rails5からは今回ご紹介できなかった「ActionCable」が導入されています!次回こそはそちらについて書けたらなと思います。

 それでは、Enjoy Ruby!

注釈

*1 : 続きを読んでいただければわかりますが、すでに開発が止まっているGem達なので読んで誰が得するのかというご指摘を受けそうですが...

*2: https://github.com/igrigorik/em-websocket/blob/master/CHANGELOG.rdoc#051--2014-04-23

*3: Windows環境でrubyinstaller2を使っている場合、EventMachineをロードできない不具合があるようです(https://github.com/oneclick/rubyinstaller2/issues/96)。リンク先のIssueにも解決策の記載がありますが、「gem install eventmachine --platform ruby」のコマンドを実行することでロードできるようになります。

*4: https://qiita.com/sarutorareo/items/c5e55e8e3e00867513fc

*5: 既に新しいfaye-websocketがインストールされている場合は、「bundle update faye-websocket」を実行する必要があります。

*6: Websocket-railsがThinに依存しているため、既にThinはインストールされています。

*7: https://github.com/websocket-rails/websocket-rails/issues/407

*8: ちなみにrakeコマンドでwebsocketサーバを起動するのですが、rakeの実行結果自体は成功しているように見えるので原因調査に苦労しました(log/ websocket_rails_server.logに出力されています)。

*9: ここらへんの細かい設定内容は、次のページに記載があります。https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode

*10: 以下の画像はWindowsでのキャプチャですが、動作自体はVM上のUbuntuの上で動いています(そのためURLがlocalhostではありません)。当然のことながらバージョンが上がっていないため、以前同様Windows上では動作しません。

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  Microsoft Azure  Docker  Kubernetes