Ruby / Roda - Web Framework / Plugins / :websockets


Introduction

The :websocket plugin adds integration support for websockets.

Currently, only 'faye-websocket' is supported, so eventmachine is required for websockets. See the faye-websocket documentation for details on the faye-websocket API.

Note! faye-websocket is only supported on Ruby 1.9.3+, so the :websockets plugin only works on Ruby 1.9.3+.

Here's a simplified example for a basic multi-user, multi-room chat server, where a message from any user in a room is sent to all other users in the same room, using a websocket per room:

plugin :websockets, adapter: :thin, ping: 45

MUTEX = Mutex.new
ROOMS = {}

def sync
  MUTEX.synchronize{yield}
end

route do |r|
  
  r.get "room/:d" do |room_id|
    
    room = sync{ROOMS[room_id] ||= []}
    
    r.websocket do |ws|
      
      # Routing block taken if request is a websocket request,
      # yields a Faye::WebSocket instance
      
      ws.on(:message) do |event|
        sync{room.dup}.each{|user| user.send(event.data)}
      end
      
      ws.on(:close) do |event|
        sync{room.delete(ws)}
        sync{room.dup}.each{|user| user.send("Someone left")}
      end
      
      sync{room.dup}.each{|user| user.send("Someone joined")}
      sync{room.push(ws)}
    end

    # If the request is not a websocket request, execution
    # continues, similar to how routing in general works.
    view 'room'
    
  end
  
end

Plugin Configuration

Add default options used for websockets. These options are passed to Faye:WebSocket.new, except that the following options are handled separately.

Option Name: Description:
:adapter Calls Faye::WebSocket.load adapter with the given value, used to set the adapter to load, if Faye requires an adapter to work with the webserver. Possible options: :thin, :rainbows, :goliath

See RequestMethods#websocket for additional supported options.

def self.configure(app, opts=OPTS)
  opts = app.opts[:websockets_opts] = (app.opts[:websockets_opts] || {}).merge(opts || {})
  if adapter = opts.delete(:adapter)
    WebSocket.load_adapter(adapter.to_s)
  end
  opts.freeze
end

RequestMethods

#.websocket?

True if this request is a websocket request, false otherwise.

#. websocket(opts=OPTS)

If the request is a websocket request, yield a websocket to the block, and return the appropriate Rack response after the block returns.

opts is an options hash used when creating the websocket, except the following options are handled specially:

Option Name: Description:
:protocols Set the protocols to accept, should be an array of strings.