Amazingly easy pub/sub with Faye
Web application development has been rough river of continuous evolution. We have come a long way from the days of mostly static html content. Today there is such a variety of tools that we can use to bring our wildest imaginations to life. It is becoming quite common now to leverage Javascript frameworks such as backbone or spine with our json formatted Rails API's to create a seamless user experience that comes relatively close to feeling like a native application. Another step in this evolution is creating real time event driven sites with a pub/sub server like Faye. This will allow you to cut out all of those polling requests that are constantly pounding your web server for the very latest information and replace them with a more event driven style experience.
In the coming article we'll go over setting up a Faye server inside a standard Rails app. Additionally we will cover some basic security to allow for private channels and how you can add custom extensions to your server. Finally some suggestions about how to implement the client side Javascript and hopefully give you a bit of inspiration and a few ideas to up the game on your latest web app creations.
Setting Up Your Server
Faye lets your server side Ruby communicate with your client side so easily that you'll ask yourself, is that really it? Ryan Bates from RailsCasts did a wonderful job in episode #260 introducing Faye and then he followed it up with a private_pub gem to facilitate private channels. This is a valuable resource along with the Faye site itself (http://faye.jcoglan.com/) which has some great documentation for setting up your server in both Ruby and Node.
Getting your Faye server going is as easy as adding 'faye' to your Gemfile and then just a few lines in a rackup file. See Figure 1 for a sample faye.ru.
https://gist.github.com/3343400
Notice the log_level set to debug. This is helpful when getting started so you can see the network chatter that happens as you interact with your server. As you get to your production environment you would of course want to turn this off to help with performance and to prevent bloating your log folder. Using a yml for configuration helps with setting the domain, port and later the ssl information for the various environments.
Faye runs on one of several different event-driven servers. Check the site for the latest information. Thin was an easy choice and seems to work quite well.
If scaling is an immediate concern you may want to consider setting your "engine" parameter of your server configuration. One of the supported engines is Redis, by setting this up you will be able to have multiple servers and it wont be a problem. Again using a yml file for your redis configuration your rackup file may now look something like this. Figure 2
https://gist.github.com/3343470
Client Side
One of the things I love about the Ruby Faye server is that it delivers up its own JS library that you can include that will handle all the heavy lifting in communicating to your server. All you need to do is include the js file found at the root of your domain that you set the server to run at, for example:
https://gist.github.com/3343687
If you are unfamiliar with some of the awesome Javascript frameworks out there like backbone.js or spine I would highly recommend doing some research into what these can do to improve your existing JS code base. Many Rails developers take for granted the convenience of Active Record as the ubiquitous ORM layer. Adding a similar sense of organization to your client side model layer can bring a lot of power to your web app.
In your JS simply add a connector and an event listener and you are off and running. If you're using something like backbone in your application to store your data models you can enhance your event handler to load in the json passed up from your ruby server which will leverage all the magic in backbone to keep your views up to date. Package your published event in an event wrapper that has a object_type, event_type and a payload. The event type could be something along the lines of 'created', 'updated', 'deleted'. You could then grab your model in your backbone store by the id and perform the appropriate action. Here is a sample JS connector and event listener methods
https://gist.github.com/3343585
You could also take the route of having different listeners for different channels. Maybe you have a create and update channel for a specific model type by connecting to a very RESTful looking URI scheme. This would also work but you may end up with some more complex looking JS to handle all of the various channels.
Security
If your application has private user information that you'd like to only publish to specific clients this is also easy to handle with Faye. Out of the box you are able to subscribe to different channels just by connecting to different URI's on your server, /events versus /my_users_events for example. However what would prevent someone from tinkering with their own socket connections and listening in on someone else's communication?
Ryan Bate's private_pub gem was written to handle some of this for you. However it is quite painless to handle this on your own. It also removes some of the magic of what is going on under the hood. The Faye server has an interface for adding extensions that makes it easy to plug in a custom authentication classes and other goodies. When an incoming message is received it is possible to inspect the message type and handle it on an individual level. For example if you wanted to check all channel subscription requests and verify that the client has access to the appropriate channel simply creating a class like in Figure 4 and then adding it as an extension in your rackup file would give you the ability to have private channels to publish your events on.
https://gist.github.com/3343500
If connecting to your server from Javascript, simply pass the timestamp and access key on initialization for the round trip verification. You will need to modify your connection method to add the additional authentication information for the connection event. The Javascript interface is similar to Ruby in that you add an extension to your Faye client, Figure 5 has an example.
https://gist.github.com/3343626
For SSL support you can also configure your key and certificate information into the rackup file. These are additional parameters on the server listen command. The final look of your faye.ru may be something like Figure 6. Notice the addition of the security extension mentioned above.
https://gist.github.com/3343489
Conclusion
By adding a simple pub/sub server to your Rails apps you can very quickly create a real time experience for your users without having all the network overhead of polling. With this guide and all of the many resources online you should have a clear path to getting setup and running with your own realtime environment with Faye. Combined with the power of a JS framework like backbone your client side views could instantly display new data as it receives updates.
- Bart Elison
Team Lead, MD Dev
G+ | LI














