论坛首页 编程语言技术论坛

使用 Rails 和 Juggernaut 作即时通讯

浏览 7140 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-07-02  
Ruby on Rails 本身整合了 Prototype 和 Script.aculo.us ,开发者可以只用 Ruby on Rails 就写出纯正的 AJAX 软件。相对来说 Comet 的工具在 Rails 上还未成熟,其中最容易的可算是 Juggernaut 。 Juggernaut 包括一个 Flash Client 、一个 Push Server 和一些 Rails Helper。 它有 helper 让开发者在版面中加入 Juggernaut client ,它跟 Push Server 会保持一个持续的 XMLSocket 连接,以接收 server 传来的 javascript,用以更新 client 画面。以下我会示范怎样用 Juggernaut 做一个 Push 的网站。

系统要求

    1. Rails 1.1 或以上
    2. json gem (gem install json)
    3. eventmachine gem (gem install eventmachine 或 gem install eventmachine-win32)


使用方法
   1. 开启一个新 project,安装 juggernaut:
          rails Realtime
          cd Realtime
          script/plugin install svn://rubyforge.org//var/svn/juggernaut/trunk/juggernaut

   2. 新增一个 layout "apps/view/layout/application.rhtml" ,javascript_include_tag :defaults 一句是基本的 Rails helper , 在安装 juggernaut 后会自动包括 juggernaut 的 javascript 档。

          <html>
          	<head>
          		<%= javascript_include_tag :defaults %>
          	</head>
          	<body>
          		<%= yield %>
          	</body>
          </html>


   3. 新增一个 controller "main":
          ./script/generate controller main index

   4. 按需要修改设定档 "config/juggernaut.yml",暂时我们不用改任何东西。
   5. 新增一个 view "app/views/main/index.rhtml",form_remote_tag 是基本的 Rails AJAX function,它把 HTML FORM 的动作用 AJAX 送去 Server。listen_to_juggernaut_channels() 让 client 在载入页面后连接去指定 channel 接收 push 资料。
          <h1>Push Demo</h1>

          <%= listen_to_juggernaut_channels(['channel']) %>

          <%= form_remote_tag :url => {:action => :push} %>
          <%= submit_tag 'Push!' %>
          <%= end_form_tag %>

   6. 修改 "app/controllers/main_controller.rb",加入 push method。Juggernaut.send_data() 方法会向所有已连接的 Client 收到讯息。
          class MainController < ApplicationController
            def index
            end

            def push
              Juggernaut.send_data("alert('Hello, world!')", ['channel'])
            end
          end

   7. 是时候测试一下成果!分别启动 Rails 和启动启动 Juggernaut Push Server:
          ruby ./script/push_server
          Starting Juggernaut Push Server
          Port: 15000
          Host: 0.0.0.0

          ./script/server
          => Booting Mongrel (use 'script/server webrick' to force WEBrick)
          => Rails application starting on http://0.0.0.0:3000
          => Call with -d to detach
          => Ctrl-C to shutdown server
          ** Starting Mongrel listening at 0.0.0.0:3000
          ** Starting Rails with development environment…
          ** Rails loaded.


   8. 试着同时开启两个 browser 到 http://localhost:3000/,按下其中一页的 "Push" 按钮,两个 browser 会同时弹出一个 javascript 的 alert message!



   9. 以上例子中,由 client 到 server 的讯息由 AJAX 发送,由server 到 client 的讯息由 Juggernaut 发送,这样我们就有一个能双向、即时通讯的软件 model,至于怎样利用这种强大的力量就要由开发者去想了!

  10. 当然 Juggernaut 还有其他功能,如对单一用户发讯、动态加入和离开 channel 、用户认证、以及在用户开启和关闭 Browser 时启动 trigger action 。详情可以参看 Nicolas Cavigliano 不断更新的教学。当然也可以读 Juggernaut 的源码 ,特别是 library "vendor/plugins/juggernaut/lib/juggernaut.rb" 和 Push Server "vendor/plugins/juggernaut/media/push_serve"

  11. 以上例子的源码可以在此下载,源碼以 MIT License 發佈

研究 Juggernaut 时遇到的问题

   1. Flash 对 XMLSocket Connection 有许多限制。Juggernaut 的作者建议把 Push Server 放在 443 port ,让软件可以穿过 firewall。然而不知为何我的电脑上无论 Firefox 还是 Safari Flash 也不肯连去 443 port …

   2. 要注意 juggernaut.yml 的 HOST 和 URL ,如果你设定的是 localhost ,在 browser 中输入 127.0.0.1 是绝对不会成功的!这是 Flash 的防止 cross site socket 机制。

   3. Client 和 Push Server 使用 Socket 连结, Rails 跟 Push Server 同样使用 Socket:所有 Juggernaut 的 function 其实都会叫 Rails 开一个 Socket 连去 Push Server。每次发讯也要一个 Socket 在大型应用似乎不是一个好的想法 。

其他方案
Apache ActiveMQ 的 AJAX Polling 方案,似乎可以做到类似 Pushing 的效果,有待研究。

更新 - ApacheMQ 的 Ajax Demo 建基在 Servlet 上,除非你不介意 host 一个 Java Server 作这个用途,又不介意用 proxy 等方法解决 cross domain 问题,否则它们的 Servlet 是不能用了。

更新2 - 我用 Mongrel 的 HttpHandler 作了个类似 ApacheMQ 的 Web Demo。

( 原文:使用 Rails 和 Juggernaut 作即時通訊 http://www.reality.hk/articles/2007/06/27/734/ )
   发表时间:2007-07-02  
相關連結


0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics