#316 Private Pub
Private Pub makes it easier than ever to publish and subscribe to real-time events in a Rails app. You can use publish_to with a block of JavaScript or supply a hash for use with JSON.
- Download:
- source code
- mp4
- m4v
- webm
- ogv



Nice episode. I did the same few days ago using PusherApp together with Rbjs. It cleans up the Serverside Javascript pretty much and I ended up simply writing:
Could you write or refer me to some explanation on how you did it?
With a small little DSL that transforms into Javascript: https://github.com/buhrmi/rbjs
The code I wrote above, however, contains a bug that would reset the input field for all users.
Hi Ryan,
what if i would like to use ssl for the faye server? With fay i could specify this in it's config. How to do this with private_pub?
SSL isn't fully supported yet, but I hope to add it in a future version. See https://github.com/ryanb/private_pub/issues/18
What are channels and how do you create them? I probably should google this first but then, right place right time to ask?
Channels aren't necessarily created, they are just a name given to determine which messages are sent to which users.
Looks pretty good! ;-)
Anyone tried running a Faye server on Heroku's cedar stack?
How about security, how easy/difficult is it for an unauthorized client to subscribe to a private channel?
Ryan what is the advantage of Private_pub compared to adding a key/ pass combination to model channels like this?
( And you have to listen to a channel like "/chatroom/new/room_key/room_pass/" )
In
private_pub, each subscription has its own unique signature/key. This means you can do something like auto-expire it after a period of time. If each chatroom has only one unique secret key then it is not possible to have control over each individual subscription.Great screencast as always! Just wanted to let you know that I released my first RubyGem a few months ago (inspired by all the recent pub/sub libraries). It's called Mad Chatter. It's a host-your-pwn Ruby chat server using EventMachine and em-websocket. I'd love to get some feedback/advice/contributors. Maybe I'll switch to use private_pub. ;-)
Great cast!
Dosen't work on windows however, as the hiredis gem fails to bundle as the config, compiler and make fails since it cannot find /sys/socket.h.
Anybody tried changing the #include stmt to use winsock.h or winsock2.h???
BR
Rutger
Has anyone been successful with an nginx frontend to a faye server? I know it's a little tricky with websockets (because nginx talks HTTP 1.0 with the backend), but I was wondering about faye.
Found an example in a github issue of a nginx config: https://github.com/ryanb/private_pub/issues/18
I'm wondering, what would be a good meganism to ensure the user received the message? Im sure in some cases its important that the application is aware that the user received the message.
Probably not with a hidden form or something.
Publish_to from a controller doesn't seem to work ( States in manual this is possible ) or I misred or I did something wrong.
Say I have
IndexController#Index
PrivatePub.publish_to("/notification", "alert('blablabalabl');")
And in my /app/views/index.erb
<%= subscribe_to "/notification" %>
My understanding was this should publish to the /notifications and push the alert out, but that isn't the case. What am I missing here? Thx for the great gem
How can I push only the messages sent between the people in a one-to-one chat? Should I create a channel for every pair of users?
Also interested in this, hope Ryan can share some light on this question and the one above ;)
am interested tooo
Hi Ryan,
Great screencast as usual.
I would also recommend you check out Pusher. It is a commercial service, but provides a lot of great value out of the box (and very easy to get started with for free).
It would also probably make another great screencast.
-Scott
P.S. I have no affiliation with Pusher....I am just a big fan. :)
Maybe you could compare/contrast between Pusher and PubNub, as long as I'm dreaming :-)
PS., also no affiliation with either of the above, just interested in using them.
Hi Ryan!
I'm trying to build a chat using the private_pub,
I tracking the presence of the users using the Faye events
(http://faye.jcoglan.com/ruby/monitoring.html)
But unfortunately I find out that if I try to publish during the event I'm causing to endless loop so for doing that I should define a client on the server side (http://faye.jcoglan.com/ruby/clients.html) and again unfortunately I discovered that I don't know how to do that using private pub, can you clarify this for me?
here you can find another great explanation to what I want accomplish - http://groups.google.com/group/faye-users/browse_thread/thread/231233016e55aba2?pli=1
10x
Ryan,
it is possible to subscribe to many channels, somthing like this:
subscribe_to "{'/channel_1', '/channel_2'}"
I'm wondering this as well. I need to publish content that several different users (on their own channels) need to see.
I suppose I could do this by looping over the users and calling "subscribe_to" during each iteration, but I don't want the JavaScript to execute over and over locally.
That functionality is not available. The code:
view_helpers.rb
By the way, in case you want to subscribe to multiple channels you could do something like:
It's just an idea...
How do you deploy this on heroku cedar?
thats what am thinking but am not sure about it. What do you think?
The code up here is not any good but as frustrating as this gets. I try to host on heroku as it works most of the time.
Running 2 web: processes for the same app is not allowed on heroku. Maybe I understood that wrong. I'll try another type of process but it would help if anyone knows some answers to post them here. Just incase.
Have you found a solution. I'm struggling.
Hello Ryan and All,
I have modified the 'before' app according to the section in the example titled 'Using Private Pub in Our Applications' but private pub is failing. I am looking for troubleshooting help.
I am running Rails 3.2.
I do not see a new message appear in the browser until I refresh the screen. The development log looks good. Index.html is being rendered, just not to the browser. Here is the log:
Started GET "/" for 135.209.108.81 at 2012-02-20 15:46:37 -0800
Processing by MessagesController#index as /
Message Load (8.2ms) SELECT
messages.* FROMmessagesRendered messages/_message.html.erb (90.4ms)
Rendered messages/index.html.erb within layouts/application (94.5ms)
Completed 200 OK in 132ms (Views: 109.4ms | ActiveRecord: 8.9ms)
Only after I refresh either broswer do I see the chat list. In the log, after the refresh, we see:
Started GET "/assets/application.css?body=1" for 135.209.108.81 at 2012-02-20 15:46:38 -0800
Served asset /application.css - 304 Not Modified (0ms)
Started GET "/assets/messages.css?body=1" for 135.209.108.81 at 2012-02-20 15:46:38 -0800
Served asset /messages.css - 304 Not Modified (0ms)
Beofre I modified the chatter-before app as per the tutorial, the browser submitting the update was updated by ajax. Now, after the modification to use private_pub, the submitting browser must be refreshed to see a new message.
When pointing the browser at the http://myserver:9292, the server responds with the following message:
Sure you're not looking for /faye ?
Thanks. I will post the solution when I know what it is.
And the problem was: The browser. Works in Firefox 9.0.1. Cheers.
Thanks Ryan! Private_pub really is a Gem. May I suggest a tiny, tiny, three character tweak would make it even more fun:
In app/views/messages/create.js.erb,
Change ".append" to ".prepend", like this:
<% publish_to "/messages/new" do %>
$("#chat").prepend("<%= j render(@message) %>");
<% end %>
$("#new_message")[0].reset();
Restart Mongrel (or your WebServer).
Now, each new micropost will be on top, and you won't have to scroll using the side bar to view it at the bottom.
even better,
<% publish_to "/messages/new" do %>
$("#chat").append("<%= escape_javascript render(@message) %>");
$("#chat").animate({ scrollTop: $("#chat").height() }, "fast");
<% end %>
This second line makes sure that the scroll is animated to the bottom so that it shows the newly appended message!
Can some one please teach me how to config and run Private_pub on Heroku? Thanks.
I just spent some time and made it. not sure if you have already figured it out or not.
After you deployed your Ruby web app (Rails, Sinatra, ...) to heroku, you should setup another heroku apps for Faye. Either you use the same Ruby web app source code or use Faye-Heroku-Cedar.
to start the Faye correctly on heroku, the key point is about the Procfile.
what Procfil does in this case is just running the "rakeup -R private_pub.ru" command to start the service.
checkout Faye-Heroku-Cedar and heroku document about Procfile
@3dd13 could you show me your Procfile as your explanation is throwing me off a bit. Is
"rakeup -R private_pub.ru"NOTE 'rakeup' a typo? Thanks.My Procfile looks like this:
@3dd13
My Procfile looks like this:
Edited after reading your codaholic_chatroom on github
WORKS NOW I CAN SECURE THE CHAT
Just wondering the difference btwn
$RAILS_ENVvs$RACK_ENVhello Nelson,
I'm trying to run private_pub on heroku.
for test purpose I tryed to run private_pub.ru on a distant server.
But my app won't connect (connection refused) regardless of my private_pub.yml file.
[it seems that on both server (app and private_pub) I can put anything as a server i does not affect the result]
Even with server: http//dumpexample.com:9292/faye on my yml. If i run private_pub.ru on local (same server as app) and it works.
They must be something i don't get on the way private_pub is working.
please could you give me you private_pub.yml on both site (app and private_pub)
Thanks a lot
A note to anyone using this gem with seyhunak / twitter-bootstrap-rails gem.
if you use rails g bootstrap:layout to generate your application layout, you will need to go into the layout and take the javascript_include tag out of the very bottom of the layout and move it up to the top of it under the stylesheet_include tag or private_pub will not work!
Fought this issue for a couple hours.
could you explain what exactly you remove? Have problems with private pub also using simple_form but no idea to what line you are referring to, thx!
just a supplement to Steven. I had problem with that as well.
If you use Firebug, you should see an javascript error in the console saying PubSub not found or undefined (something like that).
It is because in the layout twitter-bootstrap-rails put the <%= javascript_include_tag "application" %> at the bottom.
which is after the <%= subscribe_to .... %> is being called.
so, by moving that <%= javascript_include_tag "application" %> back to the top. the private_pub should work well with bootstrap-rails generated code
you are awesome. thank you.
Great Gem Ryan. Thank you!
I am trying to set up Private_Pub for my application.
I need to display a list of all the users who are online at a given time.
Any ideas how to do this???
sounds like you are handling 2 different use cases:
* data publishing and subscription
* keep-alive ping-pong
I suggest do not use private_pub to keep track if user is opening the website in the browser. instead, go deep into faye and use the ping feature.
have a look at:
https://github.com/faye/faye-websocket-ruby
gem 'thin' should be in Gemfile for this to work:
rackup private_pub.ru -s thin
And another issue.
private_pub.ru should contain:
Faye::WebSocket.load_adapter('thin')Taken from https://github.com/faye/faye/issues/128
Hi Ryan, great work on this gem!
However, how do you test it? Capybara-webkit does not seem to like it:
Great episode as always. I'm a newb and working on my first app which will require real-time chat for users. I may be asking the wrong question here, but how would you go about private pub allowing a logged in user to display their name in the channel. Things could get messy with more than two users.
Thanks for your hard work!
I'm in the same boat, I'd love a little guidance on this.
Hi Everyone,
I'm trying to work with https, I used this configuration (https://github.com/ryanb/private_pub#serving-faye-over-https-with-thin)
and I declared the gem directly from github gem "private_pub", :git => "https://github.com/ryanb/private_pub.git".
I'm pretty sure that the certificates place correctly and I'm still getting this error while I'm trying to publish something:
Exception
OpenSSL::SSL::SSLError
Error
SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A
Thanks a lot
Seems EventMachine is broken as of right now, so the gem install fails.
it does not automatically update, how to we fix this?
Hi Ryan
I am trying to set up Private_Pub but I have a conflict with Rack.
I see this message:
You have already activated rack 1.4.1, but your Gemfile requires rack 1.3.6. Using bundle exec may solve this. (Gem::LoadError)setup'from /Users/bedomax/.rvm/gems/ruby-1.9.2-p290@global/gems/bundler-1.0.21/lib/bundler/runtime.rb:17:in
from /Users/bedomax/.rvm/gems/ruby-1.9.2-p290@global/gems/bundler-1.0.21/lib/bundler.rb:110:in
setup'...........My rails is Rails 3.1.3 and Ruby ruby 1.9.2.
Thanks for your help.
Regards
Maximiliano
I can't make this work on an iPhone browser. Does anyone know why?
I have created a project exactly like in the video, it works on every browser on my computers, but it doesn't work on any iPhone browser.
Whenever I press the send button, it doesn't do anything, not even clean the textbox. It does update every other browsers I have open at the time, except the one in the iphone or any other iphones viewing the same page.
Hi
I tried this gem today
if you follow this video, your faye server :9292 is in production env, but your rails server :3000 is in development env.
so when you access from remote anything but localhost, you describe your faye server address in "config/private_pub.yml".
like this....
development:
server: "http://192.168.1.20:9292/faye"
secret_token: "secret"
i hope it will be help
I've successed to deploy my private_sub app to heroku today
I'dont understand about rack application yet
anyway, for Faye server in Gemfile I added 3gems , private_pub, thin, and foreman
and make file 'Procfile' in rails root, like this
then git push heroku master as usual, and done
When you access faye server address, if you show message 'Sure you're not looking for /faye ?' ,
faye server is good working.
This brings me great happiness Ryan... very great happiness...
Great tutorial and great Gem!
I'm having an issue now that I'm trying to use this in production. in the private_pub.yml I have:
server: "http://mydomain.com:9292/faye"
and I keep getting "failed to load resource http://mydomain:9292/faye" in the javascript console and it doesn't work.
When I lose the port number in private_pub.yml I get a 406 error for faye.js
GET http://mydomain.com/faye.js 406 (Not Acceptable)
Any thoughts on what I'm doing wrong?
Adding the
ruby//= require private_pubto application.js is missed in the manualhiredis failed to build during
bundleso I updated rails to 3.2.8 (current at this time). Problem solved.But then Faye crashed with "undefined method `close_connection_after_writing'" anytime it was messaged. The solution was to add:
to private_pub.ru before the
PrivatePub.load_configline. This answer came from Issue #39 which claims to be fixed in the private_pub gem. That's probably true, but the source for this example project was built before that change.@denispeplin mentions this above via the complimentary Faye issue #128.
If you are interested in getting private_pub running on Heroku, consider heroku_private_pub on Github. Just configure and push it. And the readme includes some handy debugging tips at the end.
Something's not working. Heroku outputs the "looking for faye" messages, but not my messages. Have followed your debug tips, but they don't help to solve the problem. Are you sure, the port
9292 on heroku is correct? I get:
When I leave the port number off, there is no failure message anymore. (Still doesn't work though…)
I am getting the same error. I'm just using raw Faye, not private pub though. Have you found a solution?
it's cool.. thanks! :)
how can you make this work on mobile phones? is it even possible?
I resolved it by changing the server property in config/private_pub.yml from "localhost" to my dev server IP address.
You'll need to change it to something that your mobile device can access. Also, if you manually included the private_pub javascript using a javascript_include_tag with an absolute URL to localhost, you'll probably want to change it there as well.
I had to restart the app to make this work.
Hi! Whenever I hit the "send" button in the app, the thin server shuts down down due to 'segmentation fault'. Also the browser console gives this error:
Failed to load resource http://localhost:9292/faye.js
So, why is not working? I'll really appreciate someone's help. Thanks!
that's a bug with Ruby 1.9.3-p362. Using 1.9.2 gets rid of that error.
When I run
rackup private_pub.ru -s thin -E productionon ubuntu with rails 3.1.3, I get this error:>> Thin web server (v1.3.1 codename Triple Espresso) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:9292, CTRL+C to stop /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:572:in `start_tcp_server': no acceptor (RuntimeError) from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:572:in `start_server' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.3.1/lib/thin/backends/tcp_server.rb:16:in `connect' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.3.1/lib/thin/backends/base.rb:53:in `block in start' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `call' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.3.1/lib/thin/backends/base.rb:61:in `start' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/thin-1.3.1/lib/thin/server.rb:159:in `start' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.3.6/lib/rack/handler/thin.rb:13:in `run' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.3.6/lib/rack/server.rb:265:in `start' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.3.6/lib/rack/server.rb:137:in `start' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/gems/rack-1.3.6/bin/rackup:4:in `<top (required)>' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/bin/rackup:19:in `load' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/bin/rackup:19:in `<main>' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/bin/ruby_noexec_wrapper:14:in `eval' from /home/jatin/.rvm/gems/ruby-1.9.2-p320/bin/ruby_noexec_wrapper:14:in `<main>'How can I get rid of that error?
http://stackoverflow.com/questions/9572834/starting-thin-server-without-the-thin-gem-does-not-work
gem 'thin'Is necessary put into Gemfile. Lock this error at Stackoverflow
Link
I cant seem to find a good way to do access control on a published message. So i publish a message using https://github.com/railsware/smt_rails so rails and javascript can share a mustache file but i only want an edit or delete button on the message if you receive the publish and you are the creator. my question is how do you publish something that can use 1 template(mustache) that can do access control on both client and server side?
hey Ryan, you might want to delete that 'episode-316' directory from the github repo? (https://github.com/railscasts/316-private-pub) It's a redundant and confusing repeat....
Hi Ryan since you embedded faye gem, wouldn't be nice to embed this too? faye-rails
great gem by the way!
bye ;)
faye is really great ...I was using private_pub for 2 months then due to slow ajax requests and using thin server which is not suitable for thousands for connections I used nodejs server and It's more fast than ruby server but I am facing problem in security as I have a chat application and I am using the simple script for running faye
'
var http = require('http'),
faye = require('faye');
var bayeux = new faye.NodeAdapter({mount: '/faye', timeout: 45});
console.log('faye starting');
bayeux.listen(8080);
'
I hope I could find anyone who is running the nodejs server to help me
First sign in through GitHub to post a comment.