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