pub / sub in ruby

Post on 18-Dec-2014

168 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

Slides of my paris.rb talk about pub/sub in ruby

TRANSCRIPT

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

top related