#260 Messaging with Faye
Apr 04, 2011 | 13 minutes | Plugins
Faye is a subscription/publishing server which makes it easy to do push notifications within a Rails app.
- Download:
- source codeProject Files in Zip (266 KB)
- mp4Full Size H.264 Video (19.2 MB)
- m4vSmaller H.264 Video (13.5 MB)
- webmFull Size VP8 Video (36.7 MB)
- ogvFull Size Theora Video (26.5 MB)
Resources
Update February 15, 2013: Thanks to Matthew Robertson for pointing out there is a security issue with this episode. The message auth_token
needs to be cleared out in an outgoing callback to avoid leaking it to the client. See below for the code.
Note: The Faye Rack server must be run in production mode, even when in development on your local machine. Use the -E production
option as shown below. See this issue for details.
bash
gem install faye rackup faye.ru -s thin -E production curl http://localhost:9292/faye -d 'message={[channel]("/messages/new",) [data]("hello"}')
config/application.rb
require "net/http"
config/initializers/faye_token.rb
FAYE_TOKEN = "anything"
application_helper.rb
def broadcast(channel, &block) message = {:channel => channel, :data => capture(&block), :ext => {:auth_token => FAYE_TOKEN}} uri = URI.parse("http://localhost:9292/faye") Net::HTTP.post_form(uri, :message => message.to_json) end
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 # IMPORTANT: clear out the auth token so it is not leaked to the client def outgoing(message, callback) if message['ext'] && message['ext']['auth_token'] message['ext'] = {} end callback.call(message) end end faye_server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 45) faye_server.add_extension(ServerAuth.new) run faye_server
rhtml
<% broadcast "/messages/new" do %> $("#chat").append("<%= escape_javascript render(@message) %>"); <% end %> $("#new_message")[0].reset();
application.js
$(function() { var faye = new Faye.Client('http://localhost:9292/faye'); faye.subscribe("/messages/new", function(data) { eval(data); }); });