rails comet juggernaut

Posted by wxianfeng Tue, 24 Nov 2009 03:34:00 GMT
环境 : ruby 1.8.7 + rails 2.1.0 + ubuntu 8.10 desktop

comet 是 server push 技术,说白了就是 服务器端直接 推送数据到客户端,据说 是 未来能取代ajax的一门技术,comet要求客户端 和 server 要建立一个长连接,无论是http 方式 还是 socket 方式,ajax是单用户的异步请求,comet是多用户异步请求,这个技术 已经应用的很广了,特别对于一些 交互性 和 实时性 要求比较高的 系统,例如 股票 实时刷新,web聊天(web qq,gtalk,meebo.com等等),实时提醒(xiaonei.com) 等功能,

那么 在rails中 有这样的comet现成东西吗? 答案是有,juggernaut 插件,juggernaut 原理是什么呢,官网是这样 说的:

1,客户端A 和 comet server 建立一个 socket 连接 (注意这里的server 是 juggernaut的 server)

2,客户端B 向 rails server 发送一个 异步 ajax 请求 (例如这里的rails server 开发环境下为 webrick)

3,rails server 发送数据 给comet server

4,comet server 广播数据到 客户端 (客户端用户可以指定)

plugin 依赖的 库 :

* Rails 2.0.2 or edge

* json gem (gem install json)

* EventMachine gem (gem install eventmachine)

* juggernaut gem (gem install juggernaut)

demo: 实时聊天室

基于 prototype || jQuery

1,新建 rails project

2,安装插件

script/plugin install http://juggernaut.rubyforge.org/svn/trunk/juggernaut


安装完后 会在 config 下看到 juggernaut 的 host 文件

3,配置 host 文件

:hosts:
  - :port: 5001 # 默认就是5001
    :host: 192.168.1.3 # 你电脑的ip
    :public_host: 192.168.1.3
    :public_port: 5001


4,cd 到 config 目录下,生成 juggernaut 的 配置文件

juggernaut -g juggernaut.yml


会在 config下 看到 juggernaut.yml 文件

4,配置 juggernaut.yml

     :allowed_ips: 
                  - 127.0.0.1
                  - 192.168.1.3 # 添加你电脑的ip


5,开启 juggernaut

juggernaut -c juggernaut.yml


显示成 Starting Juggernaut server 0.5.8 on port: 5001... 这样就已经开启了,不要以为还在 start 当中

6,controller

class ChatController < ApplicationController
  
  def index
  end

  def chat_prototype    
  end

  def chat_jquery    
  end

  # prototype
  def send_data_p
    render :juggernaut do |page|
      page.insert_html :top, 'chat_data', "<li>#{h params[:chat_input]}</li>"
    end
    render :nothing => true
  end

  # jQuery
  def send_data_j
    render :juggernaut do |page|
      page["#chat_data"].prepend "<li>#{h params[:chat_input]}</li>"
      # page["#titl"].Text = "wang"
      page["#updatetitle"].click()
    end
    render :nothing => true
  end  
end


7,View

chat_prototype.html.erb (基于 prototype )

<html>
<head>
  <title>测试</title>
  <%= javascript_include_tag :defaults, :juggernaut %>
  <%= juggernaut(:debug => false) %>
</head>
<body>
  <%= form_remote_tag(
    :url => { :action => :send_data_p },
    :complete => "$('chat_input').value = ''" ) %>
  <%= text_field_tag( 'chat_input', '', { :size => 20, :id => 'chat_input'} ) %>
  <%= submit_tag "Add" %>
  </form>
  <ul id="chat_data" style="list-style:none">
  </ul>
</body>
</html>


上面的 <%= juggernaut(:debug => false) %> 就是 和 comet server 建立连接的,还有很多参数可以添加,详细到 juggernaut helper 文件中查看,例如我上面加了 :debug => false 就是 不输出 调试

chat_jquery.html.erb (基于jQuery,这个我给它加了动态改变title 的做法,原先想在action中改的,可是没成功,后来就在action中click页面button,然后button 触发js 修改title 成功)

<html>
  <head>
    <title id="titl" runat="server">测试</title>
    <%= javascript_include_tag 'jquery', 'json','juggernaut/juggernaut', 'juggernaut/jquerynaut', 'juggernaut/swfobject'  %>
    <%= juggernaut(:debug => false) %>
  </head>
  <body>
    <form action="" method="get">
      <div style="margin:0;padding:0">
      <input id="chat_input" name="chat_input" size="20" type="text" value="" />
      <input name="commit" type="submit" value="Add" />
    </form>
    
    <script>
      $(document).ready(function(){

        $('form').submit(function(){
          $.get('/chat/send_data_j', { chat_input: $('#chat_input').val() } )
          return false;
        })
      })

      function settitle() {
        var b = "新提醒";
        var c = ":^:";
        var t = new Date();
        s = t.getSeconds();
        if(s%2 == 0){
          document.title = b;
        }else{
          document.title = c;
        }
        setTimeout("settitle()", 1000);
      }

    </script>

    <div style="display:none">
      <input type='button' id="updatetitle" onclick='settitle();' value='Change Title'/>
    </div>

    <ul id="chat_data" style="list-style:none"></ul>

  </body>
</html>


注意jquery 加载的资源文件,和 prototype 的 不一样,所有资源在下载的 插件media中 可以找到

8,开启webrick

9,打开网址开始聊天

http://192.168.1.3:3000/chat/chat_jquery

多个用户 打开上面的网址就可以实时聊天了.......

ref:

http://juggernaut.rubyforge.org/

http://ajaxian.com/archives/juggernaut-comet-for-rails

http://macrochen.javaeye.com/blog/28020