• This repository has been archived on 25/May/2018
  • Stars
    star
    435
  • Rank 100,085 (Top 2 %)
  • Language
    Ruby
  • License
    MIT License
  • Created almost 13 years ago
  • Updated over 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Simple Rails glue for the Faye messaging protocol.

faye-rails

faye-rails is a Ruby gem which handles embedding Faye's rack-based server into the rails stack and providing it with access to controllers and views based on bindings and observers.

Build Status Dependency Status Code Climate

A very small demonstration app is available for your perusal on Heroku. The source is here on Github.

Heroku Add-on

If you're planning on running Faye on Heroku you're probably going to have a bad time. Take a look at MessageRocket as an alternative, and help support the author to maintain more great open source projects.

Caveat

faye-rails is used in production by a lot of folks, none of whom are me. As I don't use faye-rails in my daily life I will not be responding to issues unless they have a corresponding PR. If you'd like to take over maintaining this project then get in contact.

Embedded server

Due to the limitations of most Rack-based web servers available Faye can only be run on Thin, however if you are using thin, then you can add as many Faye servers as you want to the Rails middleware stack like so:

# application.rb
config.middleware.use FayeRails::Middleware, mount: '/faye', :timeout => 25

You can also pass a block to faye_server which will be executed in the context of the Faye server, thus you can call any methods on Faye::RackAdapter from within the block:

config.middleware.use FayeRails::Middleware, mount: '/faye', :timeout => 25 do
  # can be defined anywhere, like app/faye_extensions/mock_extension.rb 
  class MockExtension
    def incoming(message, callback)
      callback.call(message)
    end
  end

  add_extension(MockExtension.new)
end

You can also do some rudimentary routing using the map method:

config.middleware.use FayeRails::Middleware, mount: '/faye', :timeout => 25 do
  map '/widgets/**' => WidgetsController  
  map :default => :block
end

You can find more details on the #map method in the rdoc

Controller

faye-rails includes a controller for handling the binding between model events and channels with it's own DSL for managing channel-based events.

class WidgetController < FayeRails::Controller
end

Model observers

You can subscribe to changes in models using the controller's observer DSL:

class WidgetController < FayeRails::Controller
  observe Widget, :after_create do |new_widget|
    WidgetController.publish('/widgets', new_widget.attributes)
  end
end

The available callbacks are derived from the ActiveRecord callback stack. See ActiveRecord::Callbacks for more information regarding the callback queue.

See the rdoc for more information.

Channel DSL

The controller DSL elegantly wraps channel-based aspects of the Faye API so that you can easily group code based on specific channels.

Monitoring

You can make use of Faye's monitoring API by adding calls to monitor within the channel block. You are able to monitor :subscribe, :unsubscribe and :publish events. Blocks are executed within the context of a FayeRails::Controller::Monitor instance which will give you access to #client_id, #channel and #data (#data only having a value on :publish events).

class WidgetController < FayeRails::Controller
  channel '/widgets' do
    monitor :subscribe do
      puts "Client #{client_id} subscribed to #{channel}."
    end
    monitor :unsubscribe do
      puts "Client #{client_id} unsubscribed from #{channel}."
    end
    monitor :publish do
      puts "Client #{client_id} published #{data.inspect} to #{channel}."
    end
  end
end

Filtering

You can quickly and easily filter incoming and outgoing messages for your specific channel using the controller's filter API, which wraps Faye's extensions API in a concise and channel-specific way.

class WidgetController < FayeRails::Controller
  channel '/widgets' do
    filter :in do
      puts "Inbound message #{message}."
      pass
    end
  end
end

You can add filters for :in, :out and :any, which will allow you to filter messages entering the server, exiting the server or both. The block passed to the filter is executed in the context of a FayeRails::Filter::DSL instance, which gives you access to the #message method, which contains the entire message payload from the client (including meta information you wouldn't see other ways). You also have access to the #pass, #modify, #block and #drop methods which are sugar around Faye's callback system - which is accessible via the #callback method if you want to do it that way. Check out the FayeRails::Filter::DSL rdoc for more information. Please note that all filters must call callback.call either via the sugar methods or directly to ensure that requests are not lost (not to mention potential memory leaks).

Subscribing

You can easily subscribe to a channel using the 'subscribe' method inside your channel block, like so:

class WidgetController < FayeRails::Controller
  channel '/widgets' do
    subscribe do
      puts "Received on channel #{channel}: #{message.inspect}"
    end
  end
end

Non-server environments

Often you'll find yourself running the Rails environment without the server running - eg when doing background job processing, or running the console. If you have any actions which use Faye then you'll need to make sure that you have the EventMachine reactor running. The easiest solution to this is to create an initialiser in config/initializers which calls Faye.ensure_reactor_running!. For workers in production you probably also want to make sure that you are using the Redis engine for Faye to ensure that multiple server instances see the same data.

config.middleware.use FayeRails::Middleware, mount: '/faye', engine: {type: Faye::Redis, host: 'localhost'}, :timeout => 25 do
  map '/announce/**' => SomeController  
end

See more details in this issue on GitHub.

Running on Phusion Passenger

If you want to run faye-rails on passenger, make sure you are using passenger 4.0 standalone or passenger 4.0 on nginx 1.4+ for nginx with websocket support. Passenger on apache is not supported. Because passenger uses a multi-process model, you must use the faye redis backend. Add gem 'faye-redis' to your Gemfile and configure your routes like this:

config.middleware.use FayeRails::Middleware, mount: '/faye', :timeout => 25, server: 'passenger', engine: {type: Faye::Redis, host: 'localhost'}

Thanks.

Thanks to James Coglan for the excellent Faye Bayeux implementetation and great support for Faye users.

More Repositories

1

hamlbars

Some extensions to HAML to allow generation of Handlebars templates.
Ruby
179
star
2

sidekiq-promise

Treat Sidekiq jobs as asynchronous promises
Ruby
57
star
3

Muninator

Rails plugin that implements the munin-node protocol to allow Rails internals to be graphed by Munin.
Ruby
36
star
4

vivid

Vivid is a simple 2D rendering library written in Elixir.
Elixir
31
star
5

lex_luthor

Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir. Lexer in Elixir.
Elixir
31
star
6

pixie

Pixie is a PubSub server, based on the Bayeux protocol and compatible with Faye written in Elixir.
Elixir
30
star
7

Lockbox

Reversible, secure secret storing for your rails model using public/private key encryption and acts_as_lockbox.
Ruby
30
star
8

Blogomat

Demo Baseline app to do blarghing.
Ruby
25
star
9

MrDarcy

Mr Darcy is a mashup of Async Promises and DCI. You heard right.
Ruby
13
star
10

heap

Heap data structure for Elixir.
Elixir
12
star
11

IPAddrExtensions

A selection of extensions to Ruby's IPAddr module.
Ruby
12
star
12

Auditable

Rails plugin that writes audit logs for any model.
Ruby
12
star
13

ember-validatable

Simple validations for use with Ember-Model (or any Ember Object).
JavaScript
10
star
14

Baseline

An empty Rails + Ember + BDD app.
Ruby
8
star
15

bw-midi

BubbleWrapper for CoreMIDI
Ruby
5
star
16

Culvert

Packet Analysis code for Pike
4
star
17

pca9685.ex

Elixir library for the PCA9685 12-channel PWM driver.
Elixir
4
star
18

u_token

Elixir
3
star
19

ember-newsflash

JavaScript
3
star
20

micro_token

A tiny random token generator
Ruby
2
star
21

bno055.ex

Elixir library for communicating with a BNO055 over I2C.
Elixir
2
star
22

vivid_png

PNG Generation support for vivid.
Elixir
2
star
23

pixie_ets

ETS Storage backend for Pixie.
Elixir
2
star
24

FailBowl

FailBowl is a simple Gem which helps you find the source of that pesky stack overflow that many ORMs are so keen to send us.
Ruby
2
star
25

ease.ex

Simple animation easing functions
Elixir
1
star
26

elixir_decks

Card deck collection for Elixir.
Elixir
1
star
27

for_reals

A very simple demo app for ash_authentication.
Elixir
1
star
28

rnz_pips

@rnz_pips Twitter bot.
Ruby
1
star
29

ssd1306.ex

Elixir library to talk to an SSD1306 display driver over I2C using Elixir ALE.
Elixir
1
star
30

rnz_birds

@rnz_birds Twitter bot.
Ruby
1
star