Pub / Sub in Ruby
-
Upload
adrien-siami -
Category
Software
-
view
168 -
download
3
description
Transcript of Pub / Sub in Ruby
Publish / Subscribe in RubyAdrien Siami - Dimelo
@Intrepidd
What’s Pub / Sub ?
• Bidirectional communication between server and clients
• Clients subscribe to channels
• Server or client pushes events to some channels
• Clients are notified in realtime!
Use case
• Private messaging
• Broadcasting
• Server-sent events
Possible Solutions (in ruby)
• Pusher
• PubNub
• Faye
Pusher
Pros• SaaS
• Batteries Included (Auth, Presence)
Cons • SaaS
PubNubPros
• SaaS
• Batteries Included (Auth, Presence)
Cons• SaaS
• One event = one channel
FayePros
• Built with ! (And Javascript)
• Open Source and self hosted
• Extensible
• Server level hooks
• Globbing (/users/*)
• Great Maintainer (@jcoglan)
Cons
• Les batteries included
Benchmarks
Websocket Json-p Cors Failure rate
Faye 84.68% 5.46% 9.81% 0.62%
Pusher 88.4% 6,67% 4,94% 3.7%
Faye Overview - Javascript
var client = new Faye.Client('http://foo.bar/faye'); !client.subscribe('/user/123', function(message) { console.log(message.content); }); !client.publish('/user/999', {content: 'Hey dude wassup?'});
Faye Overview - Rubyrequire 'faye' require 'eventmachine' !EM.run { ! client = Faye::Client.new('http://foo.bar/faye') ! client.subscribe('/user/123') do |message| puts message.content end ! client.publish('/user/999', {content: 'Hey dude wassup?'}) }
Faye Hosting
• It’s a Rack system ! I Know this.
• EventMachine, one thread, tons of connections
• In-Memory by default
• Faye engines, e.g faye-redis, for multiple process architecture
Benchmarks
Server Without redis!(1 worker)!
With redis!(1 worker)
with redis !(4 workers)
Passenger + nginx 43 sec 1m 25 sec 53 sec
Node! 1m 18 sec 1m 42 sec
Thin 38 sec 1m 28 sec
Puma 30 sec 1m 28 sec 43 sec
• Connect 10k clients • Subscribe • send some messages • disconnect
Gotchas
• Tune your file descriptors
• Use EM.epoll
• PhusionPassenger.advertised_concurrency_level = 0
• passenger_max_requests 0;
DIY !
• Authentication
• Presence
Faye Authentication
• JWT based signature, generated by the Rails Server when allowed
• Inserted into the faye request through a plugin executing an Ajax Call
• Check at the faye server level
dimelo/faye-authentication
Faye AuthenticationIn a controller app (route /faye/auth):
def auth if can?(:read, params[:message].try(:channel)) render :json => {signature: Faye::Authentication.sign(params[:message], 'faye secret')} else render :text => "Forbidden", :status => '403' end
In your JS :
client.addExtension(new FayeAuthentication(client));
Faye AuthenticationOn the faye server (config.ru):
server = Faye::RackAdapter.new mount: '/faye' server.add_extension Faye::Authentication::ServerExtension.new('faye secret') run server
Faye Presence
• Keep track of several clients per user
• Notify connection / disconnection
• Keep infos about the session (away / available)
Faye Presence
{ "event": "user-disconnected", "user": { "id": 42, "infos" : { "status": "away" } } }
Thank you.
Dimelo contest!• Submit a pull request on a 20+ stars ruby Github repository • Have it merged • Have a chance to win a Xbox One or a PS4 • http://contest.dimelo.com • http://jobs.dimelo.com