11月 012012
良い感じのgem sinatra-cometioを作ったのでこっちを使うと良いと思います
—
チャットを作ってみた。
http://shokai-comet-chat.herokuapp.com/
Chrome/Safari/Firefox/Android/iPod touchで動いた。
sinatra/streaming
sinatra-contribにsinatra/streamingというのがあった。eventmachineを使っているサーバー(thinなど)で動くらしい。herokuでも動いた。Sinatra::Streaming (part of Sinatra::Contrib)
本気で使うには厳しいしnode.jsを使えばいいと思うけど、Rubyでちょっとしたツールを作るのには便利そう。
一応同時に1000接続までは耐えた。ただ、Cometだとクライアント側とサーバー側両方で1分ぐらいでタイムアウトさせて接続しなおしたりするわけだから、タイミングが悪かったり接続が残ったりする事があると思うので少なめに見積もったほうがいいと思う。
実装は楽だし、ポートを1つしか使わないのでイントラ内で使うようなちょっとしたツールにリッチなUI付けたい時とかに便利そう。
arduino_firmataをwebからゴリゴリ触れるとか。
getやpostの中でstreamブロックを宣言すると、任意のタイミングでレスポンスを返せる。IOっぽく扱える。
getするとpostでデータが入るまで待たされる簡単な例
https://gist.github.com/3989831
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
require 'thin'
require 'sinatra/streaming'
@@comet = Hash.new
post '/comet/:channel' do
channel = params['channel']
data = params[:data]
@@comet[channel] = data
data
end
get '/comet/:channel' do
channel = params['channel']
stream do |s|
data = nil
loop do
break if (data = @@comet.delete channel)
sleep 1
end
s.write data
s.flush
end
end
getすると待たされる
% curl http://localhost:4567/comet/test
postするとgetの方に”hello”がでる
% curl -d 'data=hello' http://localhost:4567/comet/test
chat
チャット
http://shokai-comet-chat.herokuapp.com/
ソースコード https://github.com/shokai/sinatra-comet-chat
/chatにgetするとlong pollingで待たされるので
https://github.com/shokai/sinatra-comet-chat/blob/master/controllers/comet.rb
ajaxしてレスポンスを待つ。受信したらすぐajaxしなおす。
https://github.com/shokai/sinatra-comet-chat/blob/master/public/js/chat.js
このchatには同時に1000接続までなら動いた。1200ぐらい接続したらthinごと死亡した。
FirefoxとChromeは、同じマシンで2つウィンドウを開いてチャットすると交互にしか受信できない。
Safariは問題ない。Chromeはシークレットモードだと両方受信できるらしい。