Search code examples
ruby-on-railsfaye

Publish errors with the Faye-Rails gem


I'm using the faye-rails gem for asynchronous messaging between the javascript in my frontend and my rails server. I can send messages using curl and have the javascript print them, so I know the faye server is running. I can also listen to messages on the server like this:

# In application.rb
config.middleware.use FayeRails::Middleware, mount: '/bayeux', :timeout => 25 do
  map '/async/**' => FayeController
  map :default => :block
end

# In faye_controller.rb
class FayeController < FayeRails::Controller
  channel '/async/test' do
    subscribe do
      puts "Received on channel #{channel}: #{message.inspect}"
    end
  end
end

Then I receive messages sent via curl -X POST localhost:3000/bayeux -H 'Content-Type: application/json' -d '{"channel": "/async/test", "data": "test123"}' and get the expected output. However, I can't seem to send messages from within the server. I expected somthing like this to work, in the subscribe block (so it would be sent as a response to any message):

FayeController.publish '/async/test', :response => 'something'

but that crashes the whole server with an error:

in '+': no implicit conversion of nil into Array (TypeError)

and then a stack trace. Is this my fault - am I failing to set something up correctly, or misreading the documentation? Or is it a bug in the gem, in which case does anyone have a workaround?

I've actually alread had to use one workaround already due to a bug in the underlying faye library, see here.


Solution

  • You can publish to faye server using an HTTP request (like curl) from your server

        uri = URI.parse("http://localhost:3000/bayeux")
        begin
          Net::HTTP.post_form(uri, response: 'something')
        rescue Errno::ECONNREFUSED
          puts "Pushing to Faye Failed"
        end
    

    --------- Update --------------------------

    The previous code needs to be run in another thread to prevent the deadlock (run it in a back ground job using resque for example)

    You can use the following to publish in the same thread

     client = Faye::Client.new('http://localhost:3000/bayeux')
     client.publish('/async/test', {response: "something"})