GithubHelp home page GithubHelp logo

private_pub's Introduction

Unmaintained

The Private Pub gem is no longer maintained. Feel free to fork this project.

Private Pub

Private Pub is a Ruby gem for use with Rails to publish and subscribe to messages through Faye. It allows you to easily provide real-time updates through an open socket without tying up a Rails process. All channels are private so users can only listen to events you subscribe them to.

Watch RailsCasts Episode 316 for a demonstration of Private Pub.

Setup

Add the gem to your Gemfile and run the bundle command to install it. You'll probably want to add "thin" to your Gemfile as well to serve Faye.

gem "private_pub"
gem "thin"

Run the generator to create the initial files.

rails g private_pub:install

Next, start up Faye using the rackup file that was generated.

rackup private_pub.ru -s thin -E production

In Rails 3.1 add the JavaScript file to your application.js file manifest.

//= require private_pub

In Rails 3.0 add the generated private_pub.js file to your layout.

<%= javascript_include_tag "private_pub" %>

It's not necessary to include faye.js since that will be handled automatically for you.

Usage

Use the subscribe_to helper method on any page to subscribe to a channel.

<%= subscribe_to "/messages/new" %>

Use the publish_to helper method to send JavaScript to that channel. This is usually done in a JavaScript AJAX template (such as a create.js.erb file).

<% publish_to "/messages/new" do %>
  $("#chat").append("<%= j render(@messages) %>");
<% end %>

This JavaScript will be immediately evaluated on all clients who have subscribed to that channel. In this example they will see the new chat message appear in real-time without reloading the browser.

Alternative Usage

If you prefer to work through JSON instead of .js.erb templates, you can pass a hash to publish_to instead of a block and it will be converted to_json behind the scenes. This can be done anywhere (such as the controller).

PrivatePub.publish_to "/messages/new", :chat_message => "Hello, world!"

And then handle this through JavaScript on the client side.

PrivatePub.subscribe("/messages/new", function(data, channel) {
  $("#chat").append(data.chat_message);
});

The Ruby subscribe_to helper call is still necessary with this approach to grant the user access to the channel. The JavaScript is just a callback for any custom behavior.

Configuration

The configuration is set separately for each environment in the generated config/private_pub.yml file. Here are the options.

  • server: The URL to use for the Faye server such as http://localhost:9292/faye.
  • secret_token: A secret hash to secure the server. Can be any string.
  • signature_expiration: The length of time in seconds before a subscription signature expires. If this is not set there is no expiration. Note: if Faye is on a separate server from the Rails app, the system clocks must be in sync for the expiration to work properly.

How It Works

The subscribe_to helper will output the following script which subscribes the user to a specific channel and server.

<script type="text/javascript">
  PrivatePub.sign({
    channel: "/messages/new",
    timestamp: 1302306682972,
    signature: "dc1c71d3e959ebb6f49aa6af0c86304a0740088d",
    server: "http://localhost:9292/faye"
  });
</script>

The signature and timestamp checked on the Faye server to ensure users are only able to access channels you subscribe them to. The signature will automatically expire after the time specified in the configuration.

The publish_to method will send a post request to the Faye server (using Net::HTTP) instructing it to send the given data back to the browser.

Serving Faye over HTTPS (with Thin)

To server Faye over HTTPS you could create a thin configuration file config/private_pub_thin.yml similar to the following:

---
port: 4443
ssl: true
ssl_key_file: /path/to/server.pem
ssl_cert_file: /path/to/certificate_chain.pem
environment: production
rackup: private_pub.ru

The certificate_chain.pem file should contain your signed certificate, followed by intermediate certificates (if any) and the root certificate of the CA that signed the key.

Next reconfigure the URL in config/private_pub.yml to look like https://your.hostname.com:4443/faye

Finally start up Thin from the project root.

thin -C config/private_pub_thin.yml start

Project Status

Unfortunately I have not had time to actively work on this project recently. If you find a critical issue where it does not work as documented please ping me on Twitter and I'll take a look.

Development & Feedback

Questions or comments? Please use the issue tracker. Tests can be run with bundle and rake commands.

private_pub's People

Contributors

codezomb avatar jadencarver avatar ryanb avatar sethjackson avatar vanne avatar vic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

private_pub's Issues

IE (9) Support for PrivatePub (Websocket)

When browser does not support websocket, Faye client could disable websocket and fallback to polling. I'm wondering if this has been implemented or considered in PrivatePub.

Published content gets posted twice to the DOM, but is saved to db correctly

I'm set up similarly to the basic setup shown on the readme and in the Railscast, with the only exception being that I have to have a dynamic subscribe_to/publish_to channel. When I submit my form the published content gets appended twice to my ul. Checking the database or refreshing the page reveals that it was accurately saved to the database only once.

Any ideas? If I need to gist some code, I can do so.

How does PrivatePub start with Rails deployment in a production enviroment?

Hi, I'm tryin' to deploy this awesome gem in one of my rails app. Al works properly when I run

rackup private_pub -s thin -E production

in one command shell and in another:

rails s

But, when all I develop is workin' fine in a development enviroment, it's time to launch it up on a production server, where my Apache and Mod Passenger are well configured and my Rails app, without the private_pub channel, is working fine.

In short: what I need to configure my server in order to start Rails and PrivatePub services simultaneously?

Thx in advance

The issues is: what can I do for deploy the private_pub.ru configuration simultaneously with the existing Rails app? Do I really need to use the same command in a production environment for using private_pub?

Javascript connection error when subscribing (using heroku faye server)

When I attempt to subscribe to a channel, the following javascript error is thrown every time:

Error: Firefox can't establish a connection to the server at ws://<server-name>/faye. Source File: http://<server-name>/faye.js

Everything actually works, but it does start to fail after being loaded for some time. Additionally, I see a lot of timeout errors from the faye server:

2013-01-29T17:27:07+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path=/faye host=<server-name> fwd=108.49.41.90 dyno=web.1 queue=0ms wait=2ms connect=14ms service=30000ms status=503 bytes=0

Any suggestions for how to minimize these errors? Any additional troubleshooting suggestion?

Thanks!

( running: faye (0.8.6), private_pub (1.0.3) )

Subscribe 2 clients to each other, like IM ( documentation )

What would be the best way to use private pub to subscribe 2 clients to each other. That is 2 users having a private conversation like IM Instant Messenger.

As test setup I have now:

  • user.id 1
  • user.id 2
  • Conversation scope: subscribe_to /messages/1, /messages/2
  • Conversattion scope: publish_to /messages/1, /messages/2

This however isent a real 2-way IM, should we bundle the ids to create channel names like to1from2 and from2to1?
Would love to hear some feedback on the best way to this.

Sinatra support

This should be fairly easy to port to Sinatra/Padrino. If a specific generator isn't provided at least add a wiki page explaining how to add it.

Private Channels

Hey Ryan,

The Faye screencast you did was sweet and it's something I've been looking for for quite a while ever since I tried out PusherApp. Though I like the idea of hosting the pubsub server myself with Faye since it's a lot less expensive that way.

I was wondering whether private_pub also supports "Private Channels". For example: say you have a channel like /chat_sessions/512 and you are able to invite people over to chat, but you don't want random people just signing in to that chat session. Is there a way to "authenticate" who can and cannot access that particular channel?

PusherApp has a way to handle that, and is described here:
http://pusherapp.com/docs/private_channels

I used it before, wasn't too hard to set up. Might be a nice addition (if you haven't added it already) to private_pub.

Does private_pub support it, or are there any plans to support this kind of functionality?

Thanks!

Exclude Clients

It would be nice if the publish_to method had an :exclude option where one could remove certain client ids from the message. A convenient :current option could be passed to automatically exclude the current sender of the request.

For example, let's say in the classic chat example we want the chatter's message to show up immediately and not wait for the faye callback. This means the faye message should only be sent to all other clients but not the current one because we handle that outside of this request. It could be done like this.

<% publish_to "/messages/new", :exclude => :current %>
  ...
<% end %>

Improve Debugging

What should one do when it doesn't seem to be working the way it should? There should be improved error messages and handling when things go wrong and easy ways to log what is happening. There should be a debugger wiki page as well.

Here are some common problems one might run into, it would be good if Private Pub helped as much with debugging these as possible.

  • faye server isn't started or doesn't match server setting in config
  • the subscribe/publish message names don't match (i.e. publish /messages/new but subscribe to /messages/add)
  • the JavaScript in the block is in valid syntax
  • using PrivatePub.subscribe without subscribe_to call so messages are never received
  • token in faye server doesn't match rails app (such as different environment or config)
  • signature has expired
  • passing channel names without beginning with a slash with Faye

setup problem on simple subscribe

Hi, I have a problem to biuld up a simple notification system as Ryan has pointed in its railscast.
I have this in my view

<%= form_for Bet.new, :remote => true do |f| %>
  <div id="auction_<%= auction.id %>"></div>
    <%= text_field_tag "bet[auction_id]", auction.id %>
    <%= f.submit "Bet" %>
  </div>
<% end %>
<%= subscribe_to "bets/new" %>

this is the create action for bets controller:

  def create
    @auction = Auction.find(params[:bet][:auction_id])
    @bet = Bet.new(params[:bet])
    @bet.save
  end

and I have this in create.js.erb

<% publish_to "bets/new" do %>
  alert("done");
<% end %>

I aspect that all the client show the alert, but nothing happen, in my development.log I have

Started POST "/bets" for 127.0.0.1 at 2012-03-03 12:12:01 +0100
Processing by BetsController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"6aCKDrymUu2aaRuWO9AIJOR+2p/fo5ZNEdCfBN9w7ZA=", "bet"=>{"auction_id"=>"1"}, "commit"=>"Bet"}
  Auction Load (0.4ms)  SELECT `auctions`.* FROM `auctions` WHERE `auctions`.`id` = 1 LIMIT 1
   (0.1ms)  BEGIN
   (0.1ms)  ROLLBACK
  Rendered bets/create.js.erb (3.0ms)

if it can help, my private_pub.ru

require "bundler/setup"
require "yaml"
require "faye"
require "private_pub"

Faye::WebSocket.load_adapter('thin')

PrivatePub.load_config(File.expand_path("../config/private_pub.yml", FILE), ENV["RAILS_ENV"] || "development")
run PrivatePub.faye_app

a strange thing happen after i started thin with "rackup private_pub.ru -s thin -E production"
I'm keep getting this
2012-03-03 12:31:15 [ERROR] [Faye::RackAdapter] undefined method []' for nil:NilClass Backtrace: /Users/mattialipreri/.rvm/gems/ruby-1.9.2-p290/gems/faye-0.8.0/lib/faye/adapters/rack_adapter.rb:137:inblock in handle_websocket'
/Users/mattialipreri/.rvm/gems/ruby-1.9.2-p290/gems/faye-websocket-0.4.1/lib/faye/websocket/api/event_target.rb:24:in call' /Users/mattialipreri/.rvm/gems/ruby-1.9.2-p290/gems/faye-websocket-0.4.1/lib/faye/websocket/api/event_target.rb:24:indispatch_event'
Any hint about the issue?
Thanks

Manually Removing Subscription

In some applications it may be necessary to prevent the user from listening to a channel before his signature has expired.

Imagine a multi-room chat application. Say a user enters a room and gets a signature to listen to the channel /room/123 and then leaves the room. It is still possible for him to listen to that channel until his signature expires. It would be nice if the Rails app could unsubscribe the user from a room.

# when user leaves the room
unsubscribe_to "/room/123"

To accomplish this Private Pub needs to be told some unique identifier about the user/session.

# before filter
PrivatePub.extra = current_user.id

This information will then need to be passed through the subscribe_to and unsubscribe_to calls to verify the subscription on each published message.

The only tricky part is handling the state of the unsubscribed users. I could do this in-memory on the Faye rack instance, but something more persistent may be necessary.

Before I add this, does anyone have a need for this kind of feature? I think the one-hour expiration will be enough for the majority of the applications.

Wiki missing?

There was a page on the wiki with come documentation on setting it up with nginx, but for some reason clicking wiki just redirects back to the main project page?

EDIT: sorry, long day. this is on the wrong repo.

publishing from monitor

i need to be able publishing from inside monitor

private_pub.ru

server.bind :subscribe do |client_id, channel|
  if /\/chat\/\d+\/user\//.match(channel)
    m = /\/chat\/(?<chat_id>\d+)\/user\/(?<user_id>\d+)/.match(channel)
    user_id = m[:user_id]
    chat_id = m[:chat_id]
  end
  unless redis.smembers('users_of_'+chat_id.to_s).include?(user_id)
    redis.sadd('users_of_'+chat_id.to_s, user_id)
    server.get_client.publish '/chat/1', 'test'
  end
  logger.info('SUBSCRIBE: '+client_id+' ('+user_id.to_s+'), '+channel)
end

server.get_client.publish '/chat/1', 'test' causes an error:

2012-04-27 14:08:17 [ERROR] [Faye::RackAdapter] undefined method `[]' for nil:NilClass
Backtrace:
/home/nir0/.rvm/gems/ruby-1.9.3-p125@tyu_development/gems/private_pub-1.0.1/lib/private_pub/faye_extension.rb:32:in `authenticate_publish'
/home/nir0/.rvm/gems/ruby-1.9.3-p125@tyu_development/gems/private_pub-1.0.1/lib/private_pub/faye_extension.rb:11:in `incoming'
/home/nir0/.rvm/gems/ruby-1.9.3-p125@tyu_development/gems/faye-0.8.2/lib/faye/protocol/extensible.rb:33:in `block in pipe_through_extensions'
/home/nir0/.rvm/gems/ruby-1.9.3-p125@tyu_development/gems/faye-0.8.2/lib/faye/protocol/extensible.rb:38:in `call'
/home/nir0/.rvm/gems/ruby-1.9.3-p125@tyu_development/gems/faye-0.8.2/lib/faye/protocol/extensible.rb:38:in `pipe_through_extensions'
/home/nir0/.rvm/gems/ruby-1.9.3-p125@tyu_development/gems/faye-0.8.2/lib/faye/protocol/server.rb:62:in `block in process'

do i need to pass some sort of auth key here?

EOFError end of file error with publish_to under ssl

Keep getting EOFError end of file error with publish_to when running under ssl. Acts kind of like the private_pub_token/secret_token is getting garbled somewhere when using ssl.

Returns success when running curl statement something like this:
curl https://domain.com:4443/faye -d 'message={"channel":"/the/channel", "data":"hello", "ext":{"private_pub_token":"secret_token"}'

PrivatePub.publish_to("/the/channel", "hello") Fails in browser and rails console seemingly no matter what tweaks I've made to it and the server over the past couple days.

Faye is backed with thin and server is ubuntu linux with rails running on nginx + unicorn.

Here's the the lines pertaining to private_pub from the error response:
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/private_pub-1.0.1/lib/private_pub.rb:34:in publish_message
from /usr/local/rvm/gems/ruby-1.9.3-p125/gems/private_pub-1.0.1/lib/private_pub.rb:28:in publish_to
which are:
line 34 publish_message(message(channel, data))
line 28 url = URI.parse(config[:server])

Websocket is connecting, GET requests failing (Switching Protocols?)

I'm using nginx with the tcp_proxy module.

I can curl it just fine:

# curl http://now.2u.fm:9200/faye\?message\=%5B%7B%22channel%22%3A%22%2Fmeta%2Fhandshake%22%2C%22version%22%3A%221.0%22%2C%22supportedConnectionTypes%22%3A%5B%22callback-polling%22%5D%2C%22id%22%3A%221%22%7D%5D\&jsonp\=__jsonp6__
__jsonp6__([{"id":"1","channel":"/meta/handshake","successful":true,"version":"1.0","supportedConnectionTypes":["long-polling","cross-origin-long-polling","callback-polling","websocket","eventsource","in-process"],"clientId":"jls0srprht51xb368yrojft3h4drgu0","advice":{"reconnect":"retry","interval":0,"timeout":45000}}]);#

But in my website the GET requests for that same URL are failing after a long time waiting. Any idea what's going on?

It shows HTTP1.1 and that it's "switching protocols"?
http://cl.ly/image/2Z1f2809222b

I've posted more details and screenshots on StackOverflow.

My tcp setup:

tcp {
  timeout 1d;
  websocket_read_timeout 1d;
  websocket_send_timeout 1d;

  upstream websockets {
    server 127.0.0.1:9292;
    check interval=3000 rise=2 fall=5 timeout=1000;
  }

  server {
    server_name now.2u.fm;
    listen 199.36.105.34:9200;

    timeout 64000;

    so_keepalive on;
    tcp_nodelay on;

    websocket_pass websockets;
    websocket_buffer 1k;
  }
}

I've tried with proxy_pass instead of websocket_pass but that actually causes the whole page to hang while loading.

Juggernaut adapter

I will need to research how much work it will be, but consider adding a Juggernaut adapter. One could pass a --juggernaut option to install Juggernaut specific files.

Publishing from model causes tests to fail

Because I am publishing from a model, my unit tests fail, since I'm not spinning up the faye server in the test environment. Is there a config option like:

PrivatePub.config.publish = !Rails.env.test?

It would be very helpful to not publish in testing (since it breaks the tests)

Broadcast message on client unsubscribe

I'm using private_pub to implement a one-to-one chat-like application.

Here is my story: as a user, I would like to receive a message when my partner leaves the chat – closes the window, etc.

Looking through the Faye Monitoring docs here is my attempt at binding on unsubscribe:

# Run with: rackup private_pub.ru -s thin -E production
require "bundler/setup"
require "yaml"
require "faye"
require "private_pub"
require "active_support/core_ext"

Faye::WebSocket.load_adapter('thin')

PrivatePub.load_config(File.expand_path("../config/private_pub.yml", __FILE__), ENV["RAILS_ENV"] || "development")

wts_pubsub = PrivatePub.faye_app

wts_pubsub.bind(:subscribe) do |client_id, channel|
  puts "[#{Time.now}] Client #{client_id} joined  #{channel}"
end

wts_pubsub.bind(:unsubscribe) do |client_id, channel|
  puts "[#{Time.now}] Client #{client_id} disconnected from #{channel}"
  PrivatePub.publish_to channel, { marius_says: 'quitter' }
end

run wts_pubsub

but I keep getting timeouts: [ERROR] [Faye::RackAdapter] Timeout::Error

Prying into PrivatePub#publish_to, data holds what I expect both when I'm publishing from the Rails or the private_pub app, but the private_pub app keeps hanging.

How can I get publishing from private_pub to work?

Publish_to not working

I have successfully gotten faye to work alone (pushing messages to both users), but when incorporating private_pub I have been having problems. Now the faye server starts without any errors but it still does not seem to work as expected.

Publish_to doesn't seem to work, when I wrap my append in my create.js.erb, it simply does not work (Doesn't post the message for either user).

<% publish_to "/messages/new" do %>
$("#chat").append("<%= escape_javascript render(@message) %>");
<% end %>

When I remove the publish too, it will at least post for the single user. Anyone have any suggestions on how to debug this? I can upload my whole project to github if that would be helpful in diagnosis. I followed every step in the guide and I'm using rails 3.2.

I also tried doing publish_to in the controller and still nothing happened.

ERROR] [Faye::RackAdapter] undefined method `[]' for nil:NilClass

I followed the video and read the instructions over and over and I keep getting this error when trying to use priviate_pub. I can get everything to work fine with just faye but when I try to use priviate_pub I get these nil errors. I discovered it couldn't find the 'server' variable when trying to load the chat and when I supplied it using the following

<script type="text/javascript"> PrivatePub.sign({ channel: "/messages/new", timestamp: 1302306682972, signature: "dc1c71d3e959ebb6f49aa6af0c86304a0740088d", server: "http://localhost:9292/faye" }); </script>

It worked, so I believe my config file is not being read for some reason. Has anyone else ran into this issue?

unsubscribe missing

It seems unsubscribe functionality is missing. "sign"-ing twice to the same channel makes duplicate messages.

Alternative JavaScript callback function

By default the JavaScript is passed to eval, but some like to manage it through JSON. There should be an alternative syntax for supplying a callback function to a given subscription. Here's what the documentation could look like:

Alternatively you can pass anything you want to the publish_to method (it will be converted to_json).

  publish_to "/messages/new", :chat_message => "hello world"

And then handle that in a callback in JavaScript.

  PrivatePub.subscribe("/messages/new", function(data) {
    $("#chat").append(data.chat_message);
  });

Note: the subscribe_to call is still necessary with this approach to grant the user access to that channel. The JavaScript is just a callback.

Subscribe_to not working properly

I am having some issues with getting my subscribed clients to update when a new messages is posted. I followed the railscast on this to setup everything, but whenever I publish a message it does not update on any of my clients. I added the debug logging to my private_pub.ru and can confirm the messages make it to the server:

2013-02-19 12:39:00 [INFO] [Faye::Server] Processing messages: [{"channel":"/messages/new","data":{"channel":"/messages/new","data":"message"},"ext":{"private_pub_token":"secret"}}](local: false)
2013-02-19 12:39:00 [DEBUG] [Faye::Engine::Proxy] Publishing message {"channel":"/messages/new","data":{"channel":"/messages/new","data":"message"},"ext":{"private_pub_token":null}}
2013-02-19 12:39:00 [DEBUG] [Faye::Server] Processing reply: {"channel":"/messages/new","successful":true}

My subscribe to function does not ever seem to fire though(index.html.erb):
<%= subscribe_to "/messages/new" %>

<script type="text/javascript"> PrivatePub.subscribe("/messages/new", function(data) { $("#chat").append("Test Index Message"); }); }); </script>

I know I should be using my message variable in the append but I was just testing and the "Test Index Message" string never appears.

Can anyone help me out with this issue?

Support for wildcard subscriptions

When subscribing to channels, Faye allows the channel passed to end in either one or two asterisks to match a wildcard segment or multiple segments recursively. The problem is, subscribe_to generates a signature based on the channel being subscribed to. Thus, the JS client cannot subscribe to a wildcard channel unless the exact same string is passed to the helper (and vice versa). For example, harkening back to the classic chat example, the following is not possible:

<%= subscribe_to "/updates/#{room.id}/*" %>

<script>
  var id = the_room_id();
  PrivatePub.subscribe("/updates/" + id + "/chats", function(data, channel) {
    $("#chat").append(data.chat_message);
  });

  PrivatePub.subscribe("/updates/" + id + "/events", function(data, channel) {
    process_event(data);
  });
</script>

Do you think PrivatePub should be modified to support this, or should the client be responsible for using the channel parameter in the callback to figure out what channel the event came from? If the former, how should it be handled?

Remove jQuery dependency

The current private_pub.js file is dependent upon jQuery and is just a quick hack. This needs to be cleaned up and the jQuery dependency needs to be removed.

undefined method `close_connection_after_writing' for nil:NilClass

I'm having an issue getting private_pub up and running. The error below happens when the browser attempts make a POST request to http://localhost:9292/faye. This was confirmed in FF 10.02, and Chrome 17. I'm also running this on OSX 10.7.3.

Sample app can be found @ https://github.com/gitt/private_pub_test

I also noticed that in my javascript console, I get the error.

Error during WebSocket handshake: 'Upgrade' header is missing

I've setup a very simple test app, that only subscribes to a channel, and nothing else. It includes the thin, and private pub gems. This might be a faye issue, so I'll link this issue to them as well, just in case.

/Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/faye-websocket-0.4.1/lib/faye/websocket/api.rb:75:in `block in close': undefined method `close_connection_after_writing' for nil:NilClass (NoMethodError)
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/faye-websocket-0.4.1/lib/faye/websocket/api.rb:89:in `call'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/faye-websocket-0.4.1/lib/faye/websocket/api.rb:89:in `close'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:177:in `fail'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/thin-1.3.1/lib/thin/connection.rb:155:in `unbind'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:1397:in `event_callback'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:179:in `run_machine'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/eventmachine-1.0.0.beta.4/lib/eventmachine.rb:179:in `run'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/thin-1.3.1/lib/thin/backends/base.rb:61:in `start'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/thin-1.3.1/lib/thin/server.rb:159:in `start'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/rack-1.3.6/lib/rack/handler/thin.rb:13:in `run'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/rack-1.3.6/lib/rack/server.rb:265:in `start'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/rack-1.3.6/lib/rack/server.rb:137:in `start'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/gems/rack-1.3.6/bin/rackup:4:in `<top (required)>'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/bin/rackup:19:in `load'
    from /Users/mike/.rvm/gems/ruby-1.9.2-head@private_pub_test/bin/rackup:19:in `<main>'

It doesn't work in IE8

This looks like a really useful tool, unfortunately it doesn't seem to be working in IE8.

jquery.append() multiple times

I user private_pub gem on my rails app I am using pjax also
i have a form submitted with ajax
and on my create.js.erb file I have these code

<% publish_to "/posts/#{@message.post.id}" do %>
$('ul#comments<%=comment.id%>').append('<%= escape_javascript (@comment)%>')
<% end %>
comments are appended many time
when I remove the publish_to method or reloading the page it working good
these issue made me crazy

rails3-mongoid-omniauth and private_pub

Hi Señor Bates, hi other coders,

I just followed your pretty simple howto, but cannot manage to get it working with the rails3-mongoid-moniauth rails recipe.
It took me about 5 minutes to push messages with a simple rails new app.

With the rails new project i could push messages to the view of the mongoid version. So the problem must be about pushing, not receiving.

Is there a chance to get it working with the mongoid recipe?

Thx for the nice gem!

publish_to from controller (documentation)

Publish_to from a controller doesn't seem to work (in the readme it states this is possible although the docs are not that clear on further details ) Or I misinterpreted them.

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.
It only seems to work on a create action wich is JS enabled.

@ryanb can you clarify how this works? thx for the great gem!

PrivatePub.publish_to - Incorrect token

Hello

When I will try do this:

(rdb:1) result = PrivatePub.publish_to('/new_messages', :message => "hello")

<Net::HTTPOK 200 OK readbody=true>

(rdb:1) result.body
"[{"channel":"/new_messages","error":"Incorrect token.","successful":false}]"

So PrivatePub not work for me. Any body know how to fix this issue.

Thanks!!!

Behind a proxy

Hi Ryan,
I am using PrivatePub in one of my projects.

Here is my setup:
Production server:

  • Database
  • Apache
  • Application (Passenger)
  • PrivatePub

Here is a snippet of my apache vhost file:

<VirtualHost *:443>
  ServerName ***

  SSLEngine on
  SSLCertificateKeyFile /etc/apache2/ssl-certs/***.key
  SSLCertificateFile /etc/apache2/ssl-certs/***/certnew_base64.cer

  DocumentRoot /var/webapps/***/public

  ProxyPreserveHost On
  ProxyPass /faye http://127.0.0.1:9292
  ProxyPassReverse /faye http://127.0.0.1:9292

  RailsEnv production

  <Directory /var/webapps/***/current/public>
    AllowOverride all
    Options -MultiViews
  </Directory>

  ErrorLog /var/log/apache2/www.***-error.log
</VirtualHost>

It is possible to connect to the faye server over the browser (https:://_/faye and https:://_/faye/faye.js).

But I can not publish something to the faye server over my rails app. How is it possible, that the rails app could connect to the faye server directly (not over the proxy)? In the internal network (in this example: localhost) are no port restrictions.

Summary: All traffic form a browser should routed to the proxy server to faye and all application stuff should call faye directly.

Ajax get request on subscribe

Hey everybody,

I don't know if this is the right place to post this but I was wondering the reason of the following behaviour:

In model.rb : publish_to "/channel", id: self.id .
in application.js, the PrivatePub.subscribe performs a get request to a controller passing id.
It the end the controller renders the action but it does it as many times as clients are subscribed.

Why is this happening?

SSL / HTTPS

Hi Ryan,

I'm using PrivatePub in one of my projects and it seems that I'm getting the HTTPS:// warning from Chrome because PrivatePub is trying to do something over HTTP://. I believe it may be either:

  • Tries to connect to the Faye server as defined in the private_pub.yml
  • Loads the /faye.js file over HTTP and not HTTPS

By "warning" i don't mean the huge WARNING screen, but simply this: http://cl.ly/2x0G0L3R2s092P0B282U

I was wondering if you know a way to get around this? Would it require me to purchase a new SSL certificate specifically for the Faye server?

I'm running on NGINX as my web server, Unicorn as my App Server and Thin for the Faye server.

Any pointers are greatly appreciated! Thanks

all kinds of problems trying to start private_pub in production

I have private_pub working perfectly in development.

In production, I navigate to the /current directory of my app and try to start private_pub with:

rackup private_pub.ru -s thin -E production -d

and get all kinds of errors -

"thin"
Exception `LoadError' at /usr/local/rvm/rubies/ruby-1.9.3-p125/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36 - cannot load such file -- bundler/setup
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/psych-1.2.2/lib/psych/core_ext.rb:16 - method `to_yaml' not defined in Object
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/psych-1.2.2/lib/psych/core_ext.rb:29 - method `yaml_as' not defined in Module
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/psych-1.2.2/lib/psych/core_ext.rb:37 - method `y' not defined in Kernel
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/psych-1.2.2/lib/psych/deprecated.rb:79 - undefined method `to_yaml_properties' for class `Object'
Exception `Errno::EEXIST' at /usr/local/rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/fileutils.rb:247 - File exists - /usr/local/rvm/gems/ruby-1.9.3-p125
Exception `LoadError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/addressable-2.2.7/lib/addressable/idna/native.rb:19 - cannot load such file -- idn
Exception `LoadError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/addressable-2.2.7/lib/addressable/idna.rb:20 - cannot load such file -- idn
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:192 - uninitialized constant Kernel::Thin
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:192 - uninitialized constant Kernel::Rainbows
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:192 - uninitialized constant Kernel::Goliath
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:44 - uninitialized constant Kernel::Thin

I used someone else's advice on here and started it with

RAILS_ENV=production bundle exec rackup private_pub.ru -s thin -E production -d

which led to different errors

"thin"
Exception `LoadError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/addressable-2.2.7/lib/addressable/idna/native.rb:19 - cannot load such file -- idn
Exception `LoadError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/addressable-2.2.7/lib/addressable/idna.rb:20 - cannot load such file -- idn
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:192 - uninitialized constant Kernel::Thin
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:192 - uninitialized constant Kernel::Rainbows
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:192 - uninitialized constant Kernel::Goliath
Exception `NameError' at /usr/local/rvm/gems/ruby-1.9.3-p125/gems/faye-websocket-0.4.1/lib/faye/websocket.rb:44 - uninitialized constant Kernel::Thin

My private_pub.ru file looks like

require "bundler/setup"
require "yaml"
require "faye"
require "private_pub"

Faye::WebSocket.load_adapter('thin')

PrivatePub.load_config(File.expand_path("../config/private_pub.yml", __FILE__), ENV["RAILS_ENV"] || "development")
run PrivatePub.faye_app

PrivatePub does not work in production if RAILS_ENV is not set.

Hello,

I'm new to github, rails and ruby. But before i'd make a pull request i'd like to start a discussion, to see your comments. Basically i dont know if its a real issue. When running in development mode, all goes fine. The RAILS_ENV is set to development and the private_pub gem runs fluent and the publishing and subscribing can begin.

Now in production mode if your RAILS_ENV is not set. The application will run in production mode, but your faye server will run in development experiencing "Incorrect signature." messages. Since rack does not pass the thin -E production params. A solve is to export your RAILS_ENV in the termial.
export RAILS_ENV=production
or when using bundler starting the gem with
RAILS_ENV=production bundle exec rackup private_pub.ru -s thin -E production

I wish to commit this to the readme but i'd like to know how you guys would solve this problem.

Publishing from models, background workers, etc.

Hey,

is there any way you could publish from within a model or a background worker? I've tried including the modules inside models but it'll still throw an undefined method exception for the capture method since that isn't available either, and I have no idea how to get it there either. I understand that the model might not be the most elegant location to publish messages from but I have some processes that run in the background and I would like to keep the users on the front-end updated about the "status" of these processes by publishing live updates to them.

Any idea how I could accomplish this?

Thanks!

Publish from JS

Is there a good way to enable JS clients to publish directly to faye (like you can do with FayeClient.publish("/channel", message))?
I don't like the idea that I need 2 HTTP requests to send a message if I can do it with only 1, instead of going through Rails to send.

Faye listen on specified server

Hi I need to run faye on the server pointed out in private_pub.yml, to accomplish this i made in this way

config/private_pub.yml

development:
server: "http://192.168.10.5:9292/faye"
secret_token: "secret"
test:
server: "http://192.168.10.5:9292/faye"
secret_token: "secret"
production:
server: "http://192.168.10.5:9292/faye"
secret_token: "ee9eeaf88b4f932b740dcf0ce1ddb9c5fd41ec126337540b2976b889e9967ac9"
signature_expiration: 3600 # one hour

RAILS_ENV=production bundle exec rackup private_pub.ru -s thin -E production -o 192.168.10.5

Thin web server (v1.3.1 codename Triple Espresso)
Maximum connections set to 1024
Listening on 192.168.10.5:9292, CTRL+C to stop

but I get this error on firefox
The connection to ws://192.168.10.5:9292/faye was interrupted while the page was loading.

My rails app is running on 192.168.10.5:6665 and it is correctly accessible by that url.
Any hint?
thanks

Publishing failing only in production

I'm having this issue in production while in development everything goes well. I've defined my RAILS_ENV to production and still the publishing does not work.

ActionView::Template::Error (getaddrinfo: Name or service not known):
    1: <% publish_to session_chat_path(@chat) do %>
    2:   newChatLine('<%= @text %>');
    3: <% end %>
  app/views/chat_session/chat.js.erb:1:in `_app_views_chat_session_chat_js_erb___205641738_80963220'

Any clues?

Is there a way to stub publish_to?

Hi:
I was wondering if there was a way to stub the publish_to method so I don't need to have Faye running during the tests. I've tried doing ApplicationHelper.stubs(:publish_to).returns(true) and PrivatePub::ViewHelpers::stubs(:publish_to).returns(true) but it doesn't work.

Any help would be appreciated :D

Private pub on heroku with 2 or more dynos

Hi all!

This gem was working like a champion but when i increased to 2 dynos in heroku it just stop working. Seems that request are processed by both dynos, and dynos are on different machines so somehow i get this JS error at the browser: Unexpected response code:400.

What can i do?

Thanks.

Faye Node.js adapter

It would be nice to support the Node.js adapter in Faye as well. I should provide a custom extension one can use with that. Or at least an example on the wiki.

Back button breaks functionality

I have noticed that if I leave a page that has subscribe_to to connect to a channel, and then click back in the browser, events are no longer triggered on the original page.

I assume this might be to do with the browser using some sort of internal cache and the timestamp and/or signature are not changing?

This behaviour occurs in Chrome and Safari on OS X.
Firefox behaves as expected, i.e. it still receives events after clicking back.

Status must be >=100 seen as integer

I am having a problem getting this to run. The error is:

127.0.0.1 - - [25/Jan/2012 11:07:11] "GET /faye.js HTTP/1.1" 200 - 0.0022
Rack::Lint::LintError: Status must be >=100 seen as integer
/var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/lint.rb:19:in assert' /var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/lint.rb:425:incheck_status'
/var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/lint.rb:50:in _call' /var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/lint.rb:36:incall'
/var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/showexceptions.rb:24:in call' /var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/commonlogger.rb:20:incall'
/var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/chunked.rb:43:in call' /var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/content_length.rb:14:incall'
/var/lib/gems/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:80:in block in pre_process' /var/lib/gems/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:78:incatch'
/var/lib/gems/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:78:in pre_process' /var/lib/gems/1.9.1/gems/thin-1.3.1/lib/thin/connection.rb:53:inprocess'
/var/lib/gems/1.9.1/gems/faye-0.7.1/lib/faye/thin_extensions.rb:43:in receive_data' /var/lib/gems/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:inrun_machine'
/var/lib/gems/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in run' /var/lib/gems/1.9.1/gems/thin-1.3.1/lib/thin/backends/base.rb:61:instart'
/var/lib/gems/1.9.1/gems/thin-1.3.1/lib/thin/server.rb:159:in start' /var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/handler/thin.rb:13:inrun'
/var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/server.rb:265:in start' /var/lib/gems/1.9.1/gems/rack-1.4.1/lib/rack/server.rb:137:instart'
/var/lib/gems/1.9.1/gems/rack-1.4.1/bin/rackup:4:in <top (required)>' /var/lib/gems/1.9.1/bin/rackup:19:inload'
/var/lib/gems/1.9.1/bin/rackup:19:in `

'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.