* websocket-railsインストール [#xb6505dd]
#setlinebreak(on)

Rails5 でも Apache + Passenger だと ActionCable は利用できない。
websocket-rails で Webソケット用のデーモンをスタンドアロンで起動させる環境を作った時のメモ。

最終的には、mod_proxy_wstunnel 使って全ての通信を Apache経由で行うようにしたいが、
この記事ではそこまではしない。(まずはスタンドアロンで動く環境を作る)

#contents
-- 参照
--- https://github.com/websocket-rails/websocket-rails/wiki
-- 関連
--- [[Ruby on Rails]]
--- [[Rails のインストール]]
--- [[Railsメモ]]
--- [[ApacheとRailsをmod_proxyで連携する]]
--- [[Railsをthinで複数起動してApacheでロードバランス]]
--- [[websocket-railsで特定ユーザにメッセージを送信する]]
--- [[websocket-railsで特定グループにメッセージを送信する]]


** railsプロジェクト作成 [#r5c72ab7]
#myterm2(){{
rails new websocket_rails
cd websocket_rails
}}

** Gemfile編集 [#w9f08fe8]
#myterm2(){{
vim Gemfile
gem 'faye-websocket', '0.10.0'  # 追加 faye-websocket が仕様変更されているので v0.10.0 までしか動かない
gem 'websocket-rails'           # 追加
gem 'redis'                            # 追加
gem 'devise'                            # 追加(Webとセッション共有する場合)
}}

** gemインストール [#e91ab5cb]
#myterm2(){{
bundle install --path vendor/bundle
}}

** websocket_railsインストール [#ha262a7c]
#myterm2(){{
rails g websocket_rails:install
}}

** development.rb を編集 [#xa2f8589]
#myterm2(){{
vim config/environments/development.rb
Rails.application.configure do
  .
  .
  config.middleware.delete Rack::Lock    # 追加
  config.session_store :redis_store, servers: 'redis://localhost:6379/0', expire_in: 1.day   # 追加(Webセッション共有する場合)
end
}}

** Webソケット用のデーモンをスタンドアロンで起動できるようにする [#ebb09067]
#myterm2(){{
vim config/initializers/websocket_rails.rb
#config.standalone = false
config.standalone = true
config.standalone_port = 3001
config.user_identifier = :id                 # ログインユーザのidをwebsocket接続情報のキーにする(devise, redisと合わせて使用?)
}}

** Webソケットのルーティング記述 [#ic8bcf51]
#myterm2(){{
vim config/events.rb
WebsocketRails::EventMap.describe do
  subscribe :send_message, :to => MessagesController, :with_method => :new
end
}}

** Websocket用コントローラ作成 [#na745cb5]
#myterm2(){{
vim app/controllers/messages_controller.rb
class MessagesController < WebsocketRails::BaseController
  def new
    data = { msg: 'msg recieved.' }
    #send_message :spread_message, data
    broadcast_message :spread_message, data
  end
end
}}

** 動作確認用ビューの作成 [#j85a496e]
#myterm2(){{
mkdir app/views/application
vim app/views/application/home.html.erb
}}

#myhtml2(){{
<input id="btn_send" type="button" value="test" />

<script>

  var dispatcher = new WebSocketRails("localhost:3001/websocket");
  var btn = document.getElementById("btn_send");

  btn.onclick = function(){
    dispatcher.trigger("send_message");
  };

  dispatcher.bind("spread_message", function(data) {
    console.log(data.msg);
  });
</script>
}}

** 動作確認画面用のルーティング追加 [#k883ad6a]
#myterm2(){{
vim config/routes.rb
root to:'application#home'
}}

** redisインストール(Macの Home brewでインストール) [#l8aff393]
#myterm2(){{
brew install redis
}}

** redisインストール(Macじゃない場合は https://redis.io/download を参照してインストール) [#t42c0003]
#myterm2(){{
wget http://download.redis.io/releases/redis-3.2.6.tar.gz
tar xzf redis-3.2.6.tar.gz
cd redis-3.2.6
make
}}

** devise関連 [#obf4639c]

#html(<div style="padding:10px;">)

*** インストール [#h6a05716]
#myterm2(){{
rails g devise:install
}}

*** config/environments/development.rb [#e007e1fd]
#myterm2(){{
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
}}

*** app/views/layouts/application.html.erb [#x45bd098]
#myhtml2(){{
<div style="text-align:right;color:#333;border-bottom:1px solid #333;padding-bottom:5px;">
<% if user_signed_in? %>
    <%= link_to 'プロフィール変更', edit_user_registration_path %>
    <%= link_to 'ログアウト', destroy_user_session_path, method: :delete %>
    ( <%= current_user.email %> )
<% else %>
    <%= link_to 'サインアップ', new_user_registration_path %>
    <%= link_to 'ログイン', new_user_session_path %>
<% end %>
</div>
}}

*** app/views/layouts/application.html.erb [#vf99c1d2]
#myhtml2(){{
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
}}

*** app/controllers/application_controller.rb [#rb36015d]
#myterm2(){{
class ApplicationController < ActionController::Base
  before_action :authenticate_user!   # 追加
}}

*** devise関連のビュー作成 [#x5e4b97e]
#myterm2(){{
rails g devise:views
}}

#html(</div>)

** redis起動 [#r99bb470]
#myterm2(){{
redis-server
}}

** Webソケット用のデーモンを起動 [#oc3cbff5]
#myterm2(){{
rake websocket_rails:start_server
}}

** Webソケット用のデーモンを停止 [#j54d88ac]
#myterm2(){{
rake websocket_rails:stop_server
}}

** 実装メモ [#ye40b83d]
WebsocketRails.users を使用すれば websocket controller 以外から特定のユーザにメッセージ送信できるらしい。
https://github.com/websocket-rails/websocket-rails/wiki/WebsocketRails%20Controllers
http://www.rubydoc.info/github/websocket-rails/websocket-rails/WebsocketRails#users-class_method
 
 WebsocketRails.users[myUser.id].send_message('new_notification', {:message => 'you\'ve got an upvote '})
 
 Note: you can use this method outside the websocket controller too.

※ ApplicationController に current_user  メソッドを定義しつつ、events.rb で config.user_identifier にキー項目を指定する?

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS