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