ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

チャットのサンプルはあるけどチャットルームのサンプルがない件について

わけあってWebSockets(or Comet)でチャットルーム的な何かが作れないかなーと思っています。
ここでいうチャットとチャットルームの違いをあげておくと、

チャット
不特定多数の人がひとつの部屋を共有する。すべての人は部屋での発言をすべて聞くことができ、すべての発言を隠すことができない。
チャットルーム
比較的少数の人が固まって部屋を作る。この部屋の外からは部屋に要る人の発言を聞くことはできず、部屋の中での発言は隠される。

というかんじです。ちょうどここにSinatraにWebSocketsをのっけたGemがあったのでこれを使い、サンプルを少し書き換えて実装をするとこんなかんじになると思います。

require 'sinatra'
require 'sinatra-websocket'
require 'json'

set :server, 'thin'
set :rooms, {}

get '/' do
  erb :rooms #Viewは省略
end

get '/:id' do
  if !request.websocket?
    erb :index #Viewは省略
  else
    request.websocket do |ws|
      ws.onopen do
        ws.send("Hello World!")
        settings.rooms[params[:id]] ||= []
        settings.rooms[params[:id]] << ws
      end
      ws.onmessage do |msg|
        EM.next_tick { settings.rooms[params[:id]].each{|s| s.send(msg) } }
      end
      ws.onclose do
        warn("wetbsocket closed")
        settings.rooms[params[:id]].delete(ws)
      end
    end
  end  
end

でもこれ、たとえthinでも部屋が増えてくると大変なことになるよねという気がしてきます。まああとで考えよう。