Juggernaut ですの!

Rails 向けの Comet サーバ Juggernaut を使います。サンプルとして、ごくごく簡単なチャットシステムを作ります。公式サイトは以下。

http://juggernaut.rubyforge.org/

準備

Ruby on Rails はインストール済として、他に必要なものをインストールします。と、言っても Juggernaut の gem 程度ですが。

sudo gem install juggernaut

Windows の場合は eventmachine か何かのインストールがうまくいかないかもしれませんが、その辺りは別途解決して下さい。無事にインストールが終わったら juggernaut の設定ファイルを作成します。

juggernaut -g juggernaut.yml

設定ファイルは yml で、上のコマンドで自動作成されます。後で必要になったらこのファイルを直す事で、各種設定を行う事ができます。Ruby on Rails で使うなら config ディレクトリの中あたりに入れておくと分かりやすいと思います。

次に juggernaut を立ち上げます。

juggernaut -c juggernaut.yml

先ほど作った設定ファイルを指定して -c を指定するだけでサーバが立ち上がります。デフォルトではポートは5001番を使用しますが、必要であれば juggernaut.yml で変更可能です。

ここまで無事に終われば juggernaut 側の準備は完了です。

Rails 側の変更

まずは Juggernaut 用のプラグインをインストールします。

ruby script/plugin install git://github.com/maccman/juggernaut_plugin.git

これが終われば Rails 側で書き換えるのは、適当なコントローラと対応するビューだけです。データを保存しないのであれば ActiveRecord は使用しないので、モデルも必要ありません。

まずはコントローラ側から。

# chats_controller.rb
class ChatsController < ApplicationController
  def index
  end

  def send_data
    render :juggernaut do |page|
      page.insert_html :top, 'chat_section', "<li>#{h params[:chat_name]}:#{params[:chat_body]}</li>"
    end
    render :nothing => true
  end
end

以上、見ての通り Ajax を使ってビューを書き換えるだけです。必要ならここで非同期的にデータベースに値を保存してください。

次にビューの側。まず、適当な layout 等の html ヘッダを記述している部分に、以下のコードを追加します。

<%= javascript_include_tag 'prototype', :juggernaut %>

次に body 側のビューを記述します。

<%= juggernaut %>
<%= form_remote_tag(
  :url => {:action => :send_data},
  :complete => "$('chat_body').valur = ''") %>
  なまえ<%= text_field_tag('chat_name', '', {:id => 'chat_name'}) %><br />
  ほんぶん<%= text_field_tag('chat_body', '', {:size => 20, :id => 'chat_body'}) %>
  <%= submit_tag 'Talk' %>
</form>
<ul id="chat_section"></ul>

上の <%= juggernaut %> の部分はヘッダに記述しても問題ありません。他の部分は Rails のデフォルトで使えるヘルパメソッドなので、すぐに理解できると思います。

後はこの状態で Rails のサーバを立ち上げて、ブラウザからアクセスしてみれば動作が確認できると思います。このとき環境によっては Juggernaut との接続を確立するまでに数秒程度のラグが発生します。FireFox を利用している場合は FireBug で通信状況を確認できるため、あわせて使うと便利かもしれません。

LAN 内でチャットを行う

実は上のコードをそのまま使うと Juggernaut のサーバが 127.0.0.1 に指定されるため、他のマシンからは利用できなくなります。例えば LAN 内でチャットを行いたい場合、以下のように指定を行います。

<%= juggernaut :host => '192.168.1.156' %>

この指定であれば、どのマシンからアクセスした場合も 192.168.1.156 に用意された Juggernaut サーバを参照してくれます。