WebSocketでブラウザにプッシュ配信する - MessagePack-RPC+Rev-WebSocket
先日、WebSocketのサーバライブラリ Rev-WebSocket をリリースしました。
前回のエントリではブラウザ同士で通信するチャットアプリケーションを紹介しましたが、実際にはTwitterクローラやWebアプリケーションなど、別のプログラムと連携してブラウザにプッシュ配信したくなると思います。
つまり↓このように、任意のプログラムからWebSocketサーバを経由して、ブラウザにデータをプッシュ配信します:
プッシュ配信したいアプリケーションと WebSocket サーバの間は MessagePack-RPC で繋ぎます。
Rev-WebSocket と MessagePack-RPC は相性が良く、簡単に統合することができます*1。
アプリケーションから WebSocket サーバを経由してブラウザにデータを配信するコードは、↓このようになります。
require 'rubygems' require 'msgpack/rpc' # gem install msgpack-rpc require 'json' # WebSocketサーバへのRPCセッションを作成 $ws = MessagePack::RPC::Client.new('127.0.0.1', 18800) # プッシュ配信 $ws.call(:push_data, {"hello" => "world"}.to_json)
簡単ですね! ここではRubyを使っていますが、MessagePack-RPCが対応していれば他の言語からも配信できます(C++、Java、Perlなど)。
$ws はどこからでも使い回せます。
WebSocketサーバは↓このようになります。
require 'rubygems' require 'rev/websocket' # gem install rev-websocket require 'msgpack/rpc' # gem install msgpack-rpc $sockets = {} class MyConnection < Rev::WebSocket # 接続されたら呼ばれる def on_open puts "WebSocket opened from '#{peeraddr[2]}': request=#{request.inspect}" $sockets[self] = self end # メッセージが届いたら呼ばれる def on_message(data) puts "WebSocket data received: '#{data}'" end # 切断されたら呼ばれる def on_close puts "WebSocket closed" $sockets.delete(self) end end class RPCServer # すべてのブラウザに配信 def push_data(data) $sockets.each_value {|sock| sock.send_message(data) } nil end end # イベントループを作成 loop = Rev::Loop.default port = ARGV[0] || 8080 # イベントループにWebSocketサーバを登録 ws = Rev::WebSocketServer.new('0.0.0.0', port, MyConnection) ws.attach(loop) # 同じイベントループにRPCサーバも乗せる rpc = MessagePack::RPC::Server.new(loop) rpc.listen('127.0.0.1', 18800, RPCServer.new) # イベントループを開始 loop.run
このプログラムを起動しておけば、他のアプリケーションからブラウザにプッシュ配信ができるという仕組みです。
実際に動くサンプルコードが frsyuki's rev-websocket at github に入っています。
他のサンプルと併せてチェックしてみてください。
*1:両方ともRevを使っているため、Rev-WebSocket と MessagePack-RPC サーバの両方を同じI/Oループに乗せることができます。