Ubuntu 14.04 で websocket, zeroMQ
rails 、postgresql、zeroMQ、websocketを使って通信するサンプル環境を作成中 create rails project cd 任意のディレクトリ rails new test_rails_postgres -d postgresql cd test_rails_postgres bundle install --path vendor/bundle bundle exec rake db:create db:migrate テスト起動確認 cd test_rails_postgres rails server http://[サーバアドレス]:3000へアクセス git 管理開始 cd test_rails_postgres git init vim .gitignore 以下を追加 doc/ *.swp *~ .project .DS_Store .idea .secret git add . git commit -m "initial commit." テスト設定 bundle exec rails generate scaffold book title:string author:string outline:text bundle exec rake db:migrate bundle exec rails server db確認 -- database list \l -- user list select * from pg_user; -- table list \d routes の確認 http://localhost:3000/rails/info/routes rails へwebsocket実装 websocket-rails install cd test_rails_postgres vim Gemfile # 以下を追加 gem 'websocket-rails' bundle install rails g websocket_rails:install # コントローラ作成 vim app/controllers/websocket_chat_controller.rb # WebsocketRails::BaseControllerを継承 class WebsocketChatController < WebsocketRails::BaseController def message_recieve # クライアントからのメッセージを取得 recieve_message = message() # websocket_chatイベントで接続しているクライアントにブロードキャスト broadcast_message(:websocket_chat, recieve_message) end end vim config/events.rb WebsocketRails::EventMap.describe do # websocket_chatイベントのマッピング subscribe :websocket_chat, to: WebsocketChatController, with_method: :message_recieve end # クライアント rails g controller chat index vim app/views/chat/index.html.erb 以下追加 <!-- チャット表示部分 --> <ul id="chat_area"> </ul> <!-- コメントフォーム --> <input id="comment" type="text"> <input id="send" type="button" value="send"> <script> var ws_rails = new WebSocketRails("[url]:3000/websocket"); // メッセージ受信時の処理 ws_rails.bind("websocket_chat", function(message){ var message_li = document.createElement("li"); message_li.textContent = message; document.getElementById("chat_area").appendChild(message_li); }) // メッセージ送信時の処理 document.getElementById("send").onclick = function(){ var comment = document.getElementById("comment").value; ws_rails.trigger("websocket_chat", comment); } </script> vim config/environments/development.rb # 以下を追加 config.middleware.delete Rack::Lock test websocket client作成 gem install gem install websocket-client-simple client program(動かない) vim websocket_client.rb require 'rubygems' require 'websocket-client-simple' ws = WebSocket::Client::Simple.connect '[url]:3000/websocket' ws.on :message do |msg| puts msg.data end ws.on :open do ws.send 'hello!!!' end ws.on :close do |e| p e exit 1 end loop do ws.send STDIN.gets.strip end execjs install(不要) gem install execjs zeromq install cd 任意のディレクトリ git clone https://github.com/zeromq/zeromq4-x.git cd zeromq4-x # git checkout origin/v4.0.1 sudo aptitude install libtool autoconf uuid-dev ./autogen.sh #./configure --prefix=/usr/local/zmq ./configure make sudo make install ZeroMQ導入 vim Gemfile -------------------- # Use zeroMq gem 'rbzmq' #gem 'ffi-rzmq' #gem 'zqm' ffi-rzmqのバージョンが合っている2.0.1が要る? rails コントローラにZMQスレッドを立ち上げる vim websocket_chat_controller.rb --------------------------------------------------- require 'rbzmq' # WebsocketRails::BaseControllerを継承 class WebsocketChatController < WebsocketRails::BaseController context = ZMQ::Context.new publisher = context.socket ZMQ::PUB publisher.bind "tcp://*:5563" begin t = Thread.new do Thread.pass # メインスレッドが確実にjoinするように puts "[rails] Tread loop start." loop do publisher.send_string 'A', ZMQ::SNDMORE publisher.send_string "We don't want to see this." publisher.send_string 'B', ZMQ::SNDMORE publisher.send_string "We would like to see this." sleep 1 end publisher.close raise "unhandled exception" end t.join rescue p $! # => "unhandled exception" end puts "[rails] WebsocketChatController is started!!!!!" def message_recieve # クライアントからのメッセージを取得 recieve_message = message() puts "[rails] server message receive and broadcast => #{recieve_message}" # websocket_chatイベントで接続しているクライアントにブロードキャスト broadcast_message(:websocket_chat, recieve_message) end end rails server立ち上げ bundle exec rails server em-websocket in rails vim websocket_chat_controller.rb require “em-websocket” # 省略 puts “rails emwebsocket server start” # 配列ではなくEventMachineオブジェクトを生成 connections = EM::Channel.new EM::WebSocket.start(host: “172.19.1.94”, port: 3001) do |ws_conn| ws_conn.onopen do puts “connected” # EventMachine#subscribeを用い、コネクションオブジェクトと処理を登録 connections.subscribe{|message| ws_conn.send(message) } end ws_conn.onmessage do |message| # onopen内で登録した処理を呼び出し puts “received:” + message connections.push(message) end end