良い感じの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はシークレットモードだと両方受信できるらしい。