您的位置:首页 > 大数据 > 人工智能

rails开发利器:简单的push服务器 faye

2011-11-11 14:14 671 查看
使用环境

rails3, jquery, faye,jquery-rails, nofity-generator

资料
http://faye.jcoglan.com/ https://github.com/jcoglan/faye http://railscasts.com/episodes/260-messaging-with-faye https://github.com/ryanb/railscasts-episodes/blob/master/episode-260/chatter-after
init project
rails new chatter --database=mysql -J

修改database.yml 和 Gemfile文件
gem 'mysql'
gem 'jquery-rails'
gem 'nifty-generators', :group => :development

bundle
bundle install

运行jquery-rails
rails generate jquery:install --ui

修改config/application.rb
config.action_view.javascript_expansions[:defaults] = %w(jquery jquery-ui jquery_ujs)

生成脚手架
rails g nifty:scaffold Message content:string

修改表单
<%= form_for @message, :remote => true  do |f| %>
  <p>
    <%= f.text_field :content %>
  </p>
  <p><%= f.submit "Send Message" %></p>
<% end %>
增加remote,ajax访问

增加_message.html.erb页面
<li>
  <span class="created_at"><%= message.created_at.strftime("%H:%M") %></span>
  <%= message.content %>
</li>

修改new.html.erb页面
<% title "Chat" %>
<ul id="chat">
  <%= render @messages %>
</ul>
<%= render 'form' %>

修改controller
def new
    @message = Message.new
    @messages = Message.all
  end

  def create
    @message = Message.create!(params[:message])
  end

新建create.js.erb文件
$("#chat").append("<%= escape_javascript render(@message) %>");
$("#new_message")[0].reset();

install faye
gem install faye

vim faye.ru
require 'faye'
faye = Faye::RackAdapter.new(:mount => '/faye', :timeout => 25)
faye.listen(9292)
run faye
#注意,mount参数会决定文件的名称,比如 :mount => "/test", 那么引用js文件的时候,应该是 http://host.name:port/test.js

运行faye服务器
rackup faye.ru -s thin -E production

加入js代码
http://192.168.1.21:9292/faye.js

修改application.js文件
$(function(){
  var client = new Faye.Client('http://192.168.1.21:9292/faye');
  client.subscribe("/messages/new",function(data){
    eval(data);
  });
});

修改application_helper.rb
require "net/http"
module ApplicationHelper
  def broadcast(channel,&block)
    message = {:channel => channel, :data => capture(&block)}
    uri = URI.parse("http://192.168.1.21:9292/faye")
    Net::HTTP.post_form(uri, :message => message.to_json)
  end
end
capture方法,是把一段block转换成一个变量

模拟发送消息的方法:

curl http://localhost:9292/faye -d 'message={"channel":"/messages/new","data":"hello"}'


修改create.js.erb文件
<% broadcast "/messages/new" do  %>
$("#chat").append("<%= escape_javascript render(@message) %>");
<% end %>
$("#new_message")[0].reset();

加入token,增强安全

新建config/initializers/faye_token.rb

FAYE_TOKEN = "anything"


修改faye.ru服务器,增加验证

require 'faye'
require File.expand_path('../config/initializers/faye_token.rb', __FILE__)

class ServerAuth
  def incoming(message, callback)
    if message['channel'] !~ %r{^/meta/}
      if message['ext']['auth_token'] != FAYE_TOKEN
        message['error'] = 'Invalid authentication token'
      end
    end
    callback.call(message)
  end
end

faye = Faye::RackAdapter.new(:mount => '/faye', :timeout => 25)
faye.add_extension(ServerAuth.new)
faye.listen(9292)
run faye

修改applicaton_helper.rb的broadcast方法
def broadcast(channel,&block)
    message = {:channel => channel, :data => capture(&block),:ext => {:auth_token => FAYE_TOKEN}}
    uri = URI.parse("http://192.168.1.21:9292/faye")
    Net::HTTP.post_form(uri, :message => message.to_json)
  end

思路总结:

1.ruby代码向faye服务器发送一段js代码

2.faye在监听,扩送到其他的监听client

3.其他的client执行该段js代码

以前项目一直用juggernaut,但是juggernaut实在太笨重了,安装起来特别麻烦,而且对服务器端没有任何的控制。faye是一个非常不错的轻量级替代方案。

至于性能和稳定性,还需要额外的测试

这个项目可以扩展的

项目源代码地址

https://github.com/chucai/chatter
http://faye.jcoglan.com/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: