[faye websocket ruby] Any Rails example out there?

1,844 views
Skip to first unread message

Jon W

unread,
Jun 12, 2012, 1:32:50 PM6/12/12
to faye-...@googlegroups.com
Hello I'm trying to get faye-websocket-ruby running on my Rails app. Problem is I can't find any examples showing how to make it work with a Rails app. I went through the examples section in their Github but it just doesn't explain things in a way I can understand or get it running. So I was wondering if anybody could point me to the right direction here regarding my question.

Jonathan Cran

unread,
Jun 12, 2012, 1:41:50 PM6/12/12
to faye-...@googlegroups.com
On Tue, Jun 12, 2012 at 12:32 PM, Jon W <jnwe...@gmail.com> wrote:
Hello I'm trying to get faye-websocket-ruby running on my Rails app. Problem is I can't find any examples showing how to make it work with a Rails app. I went through the examples section in their Github but it just doesn't explain things in a way I can understand or get it running. So I was wondering if anybody could point me to the right direction here regarding my question.

The best rails-specific tutorial for faye i've seen is railscasts #260: http://railscasts.com/episodes/260-messaging-with-faye

jcran

Jonathan Welzel

unread,
Jun 12, 2012, 1:52:31 PM6/12/12
to faye-...@googlegroups.com
He's using 
  gem 'faye'

and I'm using 
  gem 'faye-websocket'

As the faye-websocket README states on the link I provided faye-websocket is "...a robust, general-purpose WebSocket implementation extracted from the Faye project." and uses pure Websockets for communication whereas Faye uses the bayeux protocol. Which sucks cuz I need my rails app to interact through Websockets with another app written in Scala and there aren't any Bayeux protocol clients I can use with my Scala app. Did I make myself clear? hehe
--
Jonathan Welzel

Andrew Havens

unread,
Jun 12, 2012, 9:25:04 PM6/12/12
to faye-...@googlegroups.com
Hi Jon,
Sorry I can't give a complete example here (I'm typing from my phone). First of all, i have not used this library directly, but i understand how it works. faye-websocket is using EventMachine behind the scenes, so make sure you are using a web server that supports this (thin, rainbows, or Goliath). Next, you can mount faye-websocket as Rack middleware in your application. The readme shows a simple Rack example. Then you define your Web Socket events on the new Faye::WebSocket instance. The syntax in the example looks a lot like em-websocket (which I have used before). Sorry there are a few major concepts in there that might be hard for a newbie to grasp. Maybe you could mention what area(s) you are having trouble with?
--Andrew

Jonathan Welzel

unread,
Jun 12, 2012, 10:05:42 PM6/12/12
to faye-...@googlegroups.com
Greetings Andrew
Thanks for your helpful reply.
I know about EventMachine and I got as far as starting up my Thin server using the config.ru file.
How do i mount faye-websocket as middleware? Probably using a file, but which one? Where exactly in my RoR app should it be?
How should I use the websocket server? Just start it up and there we go?

"Then you define your Web Socket events on the new Faye::WebSocket instance."
Could u be more specific please? Which file are u talking about here?

Those are te main issues for me at the moment hehe
Thanks!
--
Jonathan Welzel

James Coglan

unread,
Jun 13, 2012, 5:57:13 AM6/13/12
to faye-...@googlegroups.com
On 13 June 2012 03:05, Jonathan Welzel <jnwe...@gmail.com> wrote:
I know about EventMachine and I got as far as starting up my Thin server using the config.ru file.
How do i mount faye-websocket as middleware? Probably using a file, but which one? Where exactly in my RoR app should it be?
How should I use the websocket server? Just start it up and there we go?

It doesn't really matter where in your project you store it, but my hunch is that this will end up function much like a controller class in Rails.

A basic Rack middleware for this looks like:

class WebSocket
  def initialize(app)
    @app = app
  end
  
  def call(env)
    if Faye::WebSocket.websocket?(env)
      # handle websocket connection
    else
      @app.call(env)
    end
  end
end

You'd then require this file, wherever it is, in your config.ru file and put in front of the Rails stack:

use WebSocket
 
"Then you define your Web Socket events on the new Faye::WebSocket instance."
Could u be more specific please? Which file are u talking about here?

In the middleware above, where I've put 'handle websocket connection', you'd do something like this:

socket = Faye::WebSocket.new(env)
socket.onmessage = lambda |event|
  # event.data is the message text
end
socket.onclose = lambda |event|
  socket = nil
end

Then it's up to you to do whatever you want with incoming messages. You can use your Rails models or any other internal code here.

Jon W

unread,
Jun 13, 2012, 7:46:44 AM6/13/12
to faye-...@googlegroups.com
Hm, it all still looks very fuzy to me
Also, wouldn't I need to do something like this?

Jonathan Welzel

unread,
Jun 13, 2012, 7:54:42 AM6/13/12
to faye-...@googlegroups.com
Just for future references there's also a Railscast that talks about Rack Middleware here.
--
Jonathan Welzel

James Coglan

unread,
Jun 13, 2012, 8:22:53 AM6/13/12
to faye-...@googlegroups.com
On 13 June 2012 12:46, Jon W <jnwe...@gmail.com> wrote:
Hm, it all still looks very fuzy to me
Also, wouldn't I need to do something like this?

As usual, this is Rails inventing its own way of using orthogonal tools. You can just use a standard Rack config.ru file, as that article says:

    # Rails.root/config.ru
    require "config/environment"
    use Rails::Rack::LogTailer
    use ActionDispatch::Static
    run ActionController::Dispatcher.new

If you insert `use WebSocket` at the top of that list, requests will pass through your WebSocket handler before being delegated to the rest of the stack.

Jonathan Welzel

unread,
Jun 13, 2012, 8:46:35 AM6/13/12
to faye-...@googlegroups.com
I see. And what about this code here? Is that the code that goes inside the middleware's "call" function?
--
Jonathan Welzel

James Coglan

unread,
Jun 13, 2012, 9:05:12 AM6/13/12
to faye-...@googlegroups.com
On 13 June 2012 13:46, Jonathan Welzel <jnwe...@gmail.com> wrote:
I see. And what about this code here? Is that the code that goes inside the middleware's "call" function?

Yep. Rack apps/middlewares are anything that responds to call(env) and returns a [status, headers, body] triple -- lambdas, or classes with a call(env) method. 

Jonathan Welzel

unread,
Jun 13, 2012, 9:17:14 AM6/13/12
to faye-...@googlegroups.com
Keep getting

uninitialized constant Websocket (NameError)

when starting up Thin...
--
Jonathan Welzel

Jonathan Welzel

unread,
Jun 13, 2012, 9:25:21 AM6/13/12
to faye-...@googlegroups.com
Websocket being the class I just created
--
Jonathan Welzel

Jonathan Welzel

unread,
Jun 13, 2012, 9:40:33 AM6/13/12
to faye-...@googlegroups.com
Solved the previous error by pointing to my class file like so:

require ::File.expand_path('../lib/websocket',  __FILE__)
--
Jonathan Welzel

Jonathan Welzel

unread,
Jun 13, 2012, 9:44:13 AM6/13/12
to faye-...@googlegroups.com
Now this is the error I get when a request hits the server

!! Unexpected error while processing request: undefined local variable or method `static' for #<Websocket:0x0000000442bd38 @app=HelloFaye::Application>
--
Jonathan Welzel

Jonathan Welzel

unread,
Jun 13, 2012, 10:40:09 AM6/13/12
to faye-...@googlegroups.com
My bad, I was calling the app through a static function at the end of my "call" function inside my Websocket class instead of using the variable like so

  @app.call(env)
--
Jonathan Welzel

Jonathan Welzel

unread,
Jun 13, 2012, 10:41:45 AM6/13/12
to faye-...@googlegroups.com
Now how do I get to send some data to my clients once they open up a websocket connection with Faye?
--
Jonathan Welzel

James Coglan

unread,
Jun 13, 2012, 10:43:09 AM6/13/12
to faye-...@googlegroups.com
On 13 June 2012 15:41, Jonathan Welzel <jnwe...@gmail.com> wrote:
Now how do I get to send some data to my clients once they open up a websocket connection with Faye?

You call send() on the socket object:

socket = Faye::WebSocket.new(env)
socket.send("Hello, world!") 

Jonathan Welzel

unread,
Jun 13, 2012, 2:44:52 PM6/13/12
to faye-...@googlegroups.com
I see. That worked perfectly.

Also, is there a way to use a pub/sub communication system with faye-websocket?
--
Jonathan Welzel

Reply all
Reply to author
Forward
0 new messages