- 使用环境
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
- 修改表单
增加remote,ajax访问<%= form_for @message, :remote => true do |f| %> <p> <%= f.text_field :content %> </p> <p><%= f.submit "Send Message" %></p> <% end %>
- 增加_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
capture方法,是把一段block转换成一个变量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
模拟发送消息的方法:
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.rbFAYE_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/
rails开发利器:简单的push服务器 faye
最新推荐文章于 2024-03-16 09:30:28 发布