Giter VIP home page Giter VIP logo

websocket-rails's Introduction

Websocket-Rails

Build Status Gem Version Code Climate

If you haven't done so yet, check out the Project Page to get a feel for the project direction. Feedback is very much appreciated. Post an issue on the issue tracker or shoot us an email to give us your thoughts.

Find us on IRC #websocket-rails

Stop by #websocket-rails on freenode if you would like to chat or have any questions.

Recent Updates

Check out the CHANGELOG to find out what's new.

As of version 0.2.0, non event machine based web servers such as Phusion Passenger are supported through the use of the Standalone Server Mode.

Overview

Start treating client side events as first class citizens inside your Rails application with a built in WebSocket server. Sure, WebSockets aren't quite universal yet. That's why we also support streaming HTTP. Oh, and if you don't mind running a separate process, you can support just about any browser with Flash sockets.

Installation and Usage Guides

Handle Events With Class

Map events to controller actions using an Event Router.

WebsocketRails::EventMap.describe do
  namespace :tasks do
  
    # using a Hash to specify the target
    subscribe :create, :to => TaskController, :with_method => :create
    
    # using the same syntax as routes.rb
    subscribe :update, 'task#update'
    
    # if your controller is not a top-level object
    subscribe :create_admin, :to => Admin::TaskController, :with_method => :create

    subscribe :update_admin, 'admin/task#update'

  end
end

Trigger events using our JavaScript client.

var task = {
  name: 'Start taking advantage of WebSockets',
  completed: false
}

var dispatcher = new WebSocketRails('localhost:3000/websocket');

dispatcher.trigger('tasks.create', task);

Handle events in your controller.

class TaskController < WebsocketRails::BaseController
  def create
    # The `message` method contains the data received
    task = Task.new message
    if task.save
      send_message :create_success, task, :namespace => :tasks
    else
      send_message :create_fail, task, :namespace => :tasks
    end
  end
end

Receive the response in the client.

dispatcher.bind('tasks.create_success', function(task) {
  console.log('successfully created ' + task.name);
});

Or just attach success and failure callbacks to your client events.

var success = function(task) { console.log("Created: " + task.name); }

var failure = function(task) {
  console.log("Failed to create Product: " + product.name)
}

dispatcher.trigger('products.create', task, success, failure);

Then trigger them in your controller:

def create
  task = Task.create message
  if task.save
    trigger_success task
  else
    trigger_failure task
  end
end

If you're feeling truly lazy, just trigger the failure callback with an exception.

def create
  task = Task.create! message
  trigger_success task # trigger success if the save went alright
end

That controller is starting to look pretty clean.

Now in the failure callback on the client we have access to the record and the errors.

var failureCallback = function(task) {
  console.log( task.name );
  console.log( task.errors );
  console.log( "You have " + task.errors.length + " errors." );
}

You can stop listening to an event now by using the unbind function.

dispatcher.unbind('tasks.create_success');

Channel Support

Keep your users up to date without waiting for them to refresh the page. Subscribe them to a channel and update it from wherever you please.

Tune in on the client side.

channel = dispatcher.subscribe('posts');
channel.bind('new', function(post) {
  console.log('a new post about '+post.title+' arrived!');
});

Broadcast to the channel from anywhere inside your Rails application. An existing controller, a model, a background job, or a new WebsocketRails controller.

latest_post = Post.latest
WebsocketRails[:posts].trigger 'new', latest_post

Private Channel Support

Need to restrict access to a particular channel? No problem. We've got that.

Private channels give you the ability to authorize a user's subscription using the authorization mechanism of your choice.

Just tell WebsocketRails which channels you would like to make private by using the private_channel method in the Event Router. Then handle the channel authorization by subscribing to the websocket_rails.subscribe_private event.

WebsocketRails::EventMap.describe do
  private_channel :secret_posts
  
  namespace :websocket_rails
    subscribe :subscribe_private, :to => AuthorizationController, :with_method => :authorize_channels
  end

Or you can always mark any channel as private later on.

WebsocketRails[:secret_posts].make_private

On the client side, you can use the dispatcher.subscribe_private() method to subscribe to a private channel.

Read the Private Channel Wiki for more information on subscribing to private channels from the JavaScript client and handling the authorization in your controller.

Credit where credit is due

Big thanks to our contributors who have helped keep this project moving.

Special thanks to @nessche who provided the improved routing DSL and RSpec matcher suite.

The websocket-rails organization logo was kindly provided by Uken Games.

Development

Please check out the Development Guide if you are interested in contributing. It should cover everything you need to get up and running.

Core Team

The current websocket-rails core team consists of the following individuals:

New contributors and pull requests are always welcome.

websocket-rails's People

Contributors

adamkittelson avatar cominch avatar danknox avatar darkswoop avatar depili avatar elthariel avatar florianguenther avatar fustrate avatar glyuck avatar jackiekircher avatar jtomaszewski avatar kazw avatar korun avatar lkol avatar maharifu avatar maxpleaner avatar mhdsyrwan avatar moaa avatar nessche avatar ngauthier avatar nickdesaulniers avatar pitr avatar traxmaxx avatar uelb 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  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

websocket-rails's Issues

Standalone mode crashes websocket upon connect attempt

So far I have been unable to make it work using anything but the default settings -- When I enable standalone mode, it seems to ignore the initializer alltogether, except the log level var. -- Also, shouldnt it default back to webrick instead of thin when standalone is enabled? (because shouldnt it not be starting a thin server instance alltogether, because the rake websocket_rails:start_server manages the process?) -- Its trying to load my rails using thin in development by default for me.

Even stranger, when I do rake websocket_rails:start_server, the socket starts. I see the process running. However, as soon as I load the site in my browser and it tries to connect on whatever port Ive specified, it crashes the websocket process with the following error message.

from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/gems/rake-10.0.3/lib/rake/application.rb:110:in run_with_threads' from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/gems/rake-10.0.3/lib/rake/application.rb:95:intop_level'
from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/gems/rake-10.0.3/lib/rake/application.rb:73:in block in run' from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/gems/rake-10.0.3/lib/rake/application.rb:160:instandard_exception_handling'
from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/gems/rake-10.0.3/lib/rake/application.rb:70:in run' from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/gems/rake-10.0.3/bin/rake:33:in<top (required)>'
from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/bin/rake:19:in load' from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/bin/rake:19:in

'
from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/bin/ruby_noexec_wrapper:14:in eval' from /Users/jayre/.rvm/gems/ruby-1.9.3-p125/bin/ruby_noexec_wrapper:14:in'

Here is my initializer file, but keep in mind Ive tried various settings.

WebsocketRails.setup do |config|

Change to :debug for debugging output

config.log_level = :debug

Change to true to enable standalone server mode

Start the standalone server with rake websocket_rails:start_server

Requires Redis

config.standalone = true

Change to true to enable channel synchronization between

multiple server instances. Requires Redis.

config.synchronize = true
config.standalone_port = 3245

Uncomment and edit to point to a different redis instance.

Will not be used unless standalone or synchronization mode

is enabled.

config.redis_options = {:host => 'localhost', :port => '6379'}
end

Any ideas what could be going on? Any help much appreciated.

Events being duplicated when using with passenger

Dude you must hate me by now for opening so many issues, Im sorry! :)

Anyways, I finally got it working w/ passenger, however events are now being duplicated. I verified there is no duplication anywhere in the client side javascript, and put in logging statements in my js to log the time the event happened at. -- The events seem to be happening 10-100 milliseconds apart from each other, it varies. Any ideas what could be causing this? (or advice where I could start to debug) Works fine w no duplication on development machine.

Empty data when using channels

Hi,

I have a simple channel event in my controller:

WebsocketRails[game.to_s].trigger 'player-join', { name: "Test" }

Game is a ActiveRecord model with a custom to_s method.

Here is the client binding:

var dispatcher = new WebSocketRails('localhost:3000/websocket');

    var game_id = $("#game-id").val();
    var channel = dispatcher.subscribe('game-' + game_id);

    channel.bind('player-join', function (player) {
      alert(xinspect(player));
    });

xinspect is a simple function displaying the object's properties (from http://stackoverflow.com/a/5357478).

Here is the result I get from the event:

"id" (object) => object:
"channel" (string) => game-3
"data" (object) => object:
"success" (object) => object:
"result" (object) => object:

Hence 'data' is an empty object. What's weird is that according to this code (from https://github.com/DanKnox/websocket-rails/blob/master/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee#L90)

dispatch_channe l: (event) =>
    return unless @channels[event.channel]?
    @channels[event.channel].dispatch event.name, event.data

I should get the 'data' object in 'player'. It seems there is another layer.

I don't really understand what's happening there. It works perfectly if I use the global dispatcher (and I don't have another layer on top of the 'data' field, I only get the data).

Any idea?

Thanks!

Malicious messages cannot be filtered on channels

This issue is based on a stackoverflow question to which you've already responded too.

Consider implementing tic-tac-toe with the Websocket-rails gem with the below code. There is nothing to enforce that the client sends messages only using the main dispatcher. The 'private_game' channel is suppose to be used only by the server for broadcasting moves. But a hostile client could send random data on it with channel.trigger('new_move', randomdata);

Since channel events do not go through the Event Router and thus don't go through a Controller action, there is nothing on the server side to filter out the random spam.

Tic-tac-toe seems like it represents a common use case for Websockets. It would be useful if the Websocket-rails gem had a simple way to handle prevent malicious messages on channels.

var dispatcher = new WebSocketRails('localhost:3000/websocket');

var channel = dispatcher.subscribe_private('private_game');

channel.bind('new_move', function(move) {
  // received new move, process it
});

// later on when we want to send a move to the server we run the following code
var move = {
  square: ...;
}
dispatcher.trigger('move', move);
class TicTacToeController < WebsocketRails::BaseController
  def move
    # code to verify the move is valid and save to database
    ...

    # broadcast move to all players
    WebsocketRails[:private_game].trigger(:new_move, message)
  end
end

`instance_eval': block not supplied (ArgumentError)

Hi,
i am trying to add this gem to my project which based on rails 3.2.2 & ruby 1.9.3

and i am having this error

.rvm/gems/ruby-1.9.3-p125/gems/websocket-rails-0.1.3/lib/websocket_rails/event_map.rb:47:in `instance_eval': block not supplied (ArgumentError)

does this gem support ruby 1.9.3 ? or what to do ?

Best practice for integration into existing applications

Hi again,

Is there a way send messages through websockets directly from existing controllers? In this case it would be easy to call some additional websocket functions and do not change any existing code.

I've found in some older tickets this line

WebSocketRails[:channelname].trigger(:eventname, {:data => :here})

but i can't get it work. Plus I'm not using channels currently because I don't want to subscribe to channels in my views. All my information are handled on server side.

Support for on_error callback

Hello,

since I would like to track TCP errors I would appreciate the support of on_errorcallback on WebSocketConnection.

Thx,

Thilko

Duplicate Events in Console and External Scripts

I'm experiencing duplicate channel events on the client side when triggering them from the Rails console or external scripts. Events triggered from within Rails itself are not duplicated.

Standalone and synchronize are both enabled.

I've set up a small demonstration of the issue:

https://github.com/dterhorst/websocket_rails_error_demo

Make sure redis is running on the default localhost:6379, "rake websocket_rails:start_server" and "rails s" are running, all on the same machine. Load the app and hit each link in order. Run the last one in the Rails console. Results are shown in the text box.

The expected results are that demo 1 (rails), demo 2 (external script), and demo 3 (rails console) all trigger one event on the client.

The actual results are that demo 2 (external script) and demo 3 (rails console) each trigger the same event twice.

Executing demo 1 after demo 2 and/or 3 have been triggered still only triggers one event, as expected.

cross pollution of events when using asynchronous event handlers

Due to the global nature of controller.@_event, anything that accesses the controller's event object after the action returned will refer to the wrong event.

example:

# some_controller.rb
def slow_response
  real_text = message[:text]
  EM.add_timer(5) do # simulate some background work
    puts event.serialize
    trigger_success [real_text, message[:text]]
  end
end

now, on the js console call this

window.dispatcher.trigger('slow_response', {text: 'first'}, function (response) {console.log("response to first", response)})
window.dispatcher.trigger('slow_response', {text: 'second'}, function (response) {console.log("response to second", response)})

and observe the following js output after 5 seconds:

response to second ["first", "second"]

while the ruby console logs

["slow_response",{"id":119461,"channel":null,"data":{"text":"second"},"success":null,"result":null}]
["slow_response",{"id":119461,"channel":null,"data":["first","second"],"success":true,"result":null}]

What happens is that after 5 seconds, the response handler for the first event triggers but now runs in the context of the second event. All things using @_event now acually use a different event object. So trigger_success actually acknowledges the second event after having acted on the first event. The second event also triggers an action. Its input data now appears to be the response output data of the reply to the first call.

This also affects web sockets running in different user contexts and thus becomes a security/privacy issue. If the first event is sent by user A and the second by user B then user B receives a response for an action involving user A.

Expected behavior: the methods supplied by BaseController should work as documented, for example:

 69     # The {Event} object that triggered this action.
 70     # Find the current event name with event.name
 71     # Access the data sent with the event with event.data
 72     # Find the event's namespace with event.namespace
 73     def event
 74       @_event
 75     end

The event method does not return the object that triggered this action. It returns the last event that triggered any action within this controller. Same for any methods that use event or @_event.

Redis + websocket-rails = boom :)

Hi,

I'm trying to use redis gem from rails console, but when I'm call method from redis I got this error:

1.9.3-p286 :001 > Redis.new().hkeys :a
RuntimeError: eventmachine not initialized: evma_connect_to_server
    from /Users/t0d0r/.rvm/gems/ruby-1.9.3-p286/gems/eventmachine-1.0.0/lib/eventmachine.rb:664:in `connect_server'
    from /Users/t0d0r/.rvm/gems/ruby-1.9.3-p286/gems/eventmachine-1.0.0/lib/eventmachine.rb:664:in `bind_connect'
    from /Users/t0d0r/.rvm/gems/ruby-1.9.3-p286/gems/eventmachine-1.0.0/lib/eventmachine.rb:640:in `connect'

If I remove the websocket-rails from my Gemfile - all is OK?

I need help how to solve this problem.

Loading development environment (Rails 3.2.8)

  • em-synchrony (1.0.2)
  • eventmachine (>= 1.0.0.beta.1)
  • websocket-rails (0.2.0)

Error occurred in IE when accessing responseText

I was trying a channel example (which works well in Chrome) in IE9, and got the following error:

SCRIPT10: The data necessary to complete this operation is not yet available.
http_connection.js?body=1, line 64 character 9

The code around line 64 of the js file is as following:

HttpConnection.prototype.parse_stream = function() {
  var data, decoded_data;
  if (this._conn.readyState === 3) {
    data = this._conn.responseText.substring(this.last_pos); // <----- this line
    this.last_pos = this._conn.responseText.length;
    data = data.replace(/\]\]\[\[/g, "],[");
    decoded_data = JSON.parse(data);
    return this.dispatcher.new_message(decoded_data);
  }
};

BTW, how to enable "Flash" mode (for sake of IE browsers)? I couldn't find the documentation of it.

Thanks!

client_disconnected event fires twice on the server

If a page is loaded into a browser and a new WebSocketRails object is created, the client_connected event occurs correctly. If that page is then refreshed (Firefox 16.0.2), the client_connected event occurs again, then shortly after (~5s) the client_disconnected is triggered. The order of events is problematic for me. Is this a bug, or is there something different that I should be doing?

If the page is closed, the event happens immediately, but 5s later happened again (regardless of page refreshes).

My events.rb file looks like:
WebsocketRails::EventMap.describe do
subscribe :client_connected,
to: WebSocketController,
with_method: :client_connected
subscribe :client_disconnected,
to: WebSocketController,
with_method: :client_disconnected
end

This behavior occurs in Safari (6.0.2 (8536.26.17)) as well.

StandAlone Server Mode : Server Stops at the first "send" call

Hi,
I'm using standalone server mode

My Configurations is just :

if Rails.env.production?
  WebsocketRails.setup do |config|
    config.standalone = true
    config.redis_options = {:host => '127.0.0.1', :port => '6379'}
  end
else
  WebsocketRails.setup do |config|
    config.standalone = false
  end
end

when i send anything (like using channel.trigger), The Server stops without any error !

Here's the websocket_rails.log

I [2013-03-31 19:14:14.877] [ESC[32mSynchronizationESC[0m] Server Registered: ZLHlSUNgUa7VDW-Z6g7o_A

I [2013-03-31 19:14:44.996] [ESC[32mConnectionManagerESC[0m] Connection opened: #<Connnection::38784760>

I [2013-03-31 19:14:44.101] [ESC[32mDispatcherESC[0m] Started Event: client_connected
I [2013-03-31 19:14:44.101] [ESC[32mDispatcherESC[0m] ESC[36mName:ESC[0m client_connected
I [2013-03-31 19:14:44.101] [ESC[32mDispatcherESC[0m] ESC[36mData:ESC[0m {"connection_id"=>38784760}
I [2013-03-31 19:14:44.101] [ESC[32mDispatcherESC[0m] ESC[36mConnection:ESC[0m #<Connnection::38784760>

I [2013-03-31 19:14:44.101] [ESC[32mDispatcherESC[0m] Event client_connected Finished in 0.000093625 seconds

I [2013-03-31 19:14:44.572] [ESC[32mChannelESC[0m] #<Connnection::38784760> subscribed to channel notif_2

I [2013-03-31 19:14:48.974] [ESC[32mChannelESC[0m] #<Connnection::38784760> unsubscribed from channel notif_2

I [2013-03-31 19:14:48.975] [ESC[32mConnectionManagerESC[0m] Connection closed: #<Connnection::38784760>


Notes:

  • The application is running perfectly in development mode (without using passenger)
  • I have activated threadsafe in application.rb
  • The websocket-rails server was working before that error happened

What is the problem & how can i show more useful debugging info ?

Rails 4 does not provide ["config/routes"] key in Rails::Engine.paths

Rails 4 appears to have removed the ["config/routes"] key in Rails::Engine.paths. As a result, a conditional needs to be added to the paths appended in the WebsocketRails::Engine class to avoid explosions occurring.

I've tested out using unless paths["config/routes"].blank? and unless ::Rails.version >= '4.0.0' - both of these fix this particular issue.

Send message to every other clients

Hello, guys! Firstly, thanks for this gem. Secondly, I'm a little bit confused about the following:

If you trigger a channel event on the client, it will be sent out to every other connected client to that channel.

My code looks like something as follows:

var dispatcher = new WebSocketRails('localhost:3000/websocket');
var channel = dispatcher.subscribe('channel_name');
channel.bind('event_name', function(data) {
  console.log('channel event received: ' + data);
});
channel.trigger('event_name', object_to_send);

Soโ€ฆ I expect if I send a message from the browser, then the sender doesn't receive this message. But it doesn't work that way. As you see the sender is subscribed to the channel. I don't know but maybe it's the reason.

uninitialized constant WebsocketRails::InternalEvents::InternalController

I keep getting the above error and i get it working by patching the class as follows :

@@ -3,8 +3,8 @@
     def self.events
       Proc.new do
         namespace :websocket_rails do
-          subscribe :pong, :to => InternalController, :with_method => :do_pong
-          subscribe :subscribe, :to => InternalController, :with_method => :subscribe_to_channel
+          subscribe :pong, :to => 'InternalController', :with_method => :do_pong
+          subscribe :subscribe, :to => 'InternalController', :with_method => :subscribe_to_channel
         end
       end
     end

Large amount of data in websocket_rails.log for client_disconnected event

Using websocket-rails in standalone mode, I get a huge amount of data in the log for the client_disconnect event.

events.rb:

      subscribe :client_connected, :to => WebSocketClientsController, :with_method => :client_connected
 subscribe :client_disconnected, :to => WebSocketClientsController, :with_method => :client_disconnected

web_sockets_clients_controller.rb:

class WebSocketClientsController < WebsocketRails::BaseController

def client_connected
        WebsocketRails[:posts].trigger 'connect', current_user
end 

def client_disconnected
        WebsocketRails[:posts].trigger 'disconnect', current_user
end 

end

websocket_rails.log:

I [2013-03-05 10:02:11.373] [Channel] #Connnection::2172660360 unsubscribed from channel posts

I [2013-03-05 10:02:11.373] [ConnectionManager] Connection closed: #Connnection::2172660360

I [2013-03-05 10:02:27.343] [Dispatcher] Started Event: client_disconnected
I [2013-03-05 10:02:27.343] [Dispatcher] Name: client_disconnected
I [2013-03-05 10:02:27.382] [Dispatcher] Data: #<Faye::WebSocket::API::Event:0x0000010324ea10 @type="close", @bubbles=false, @Cancelable=false, @current_target=#<Faye::WebSocket:0x000001030051f0 @env={"SERVER_SOFTWARE"=>"thin 1.5.0 codename Knife", "SERVER_NAME"=>"localhost", "rack.input"=>#StringIO:0x0000010360e1c8, "rack.version"=>[1, 0], "rack.errors"=>#IO:, "rack.multithread"=>false, "rack.multiprocess"=>false, "rack.run_once"=>false, "REQUEST_METHOD"=>"GET", "REQUEST_PATH"=>"/websocket", "PATH_INFO"=>"/websocket", "REQUEST_URI"=>"/websocket", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_HOST"=>"localhost:3000", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:19.0) Gecko/20100101 Firefox/19.0", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en;q=0.5", "HTTP_ACCEPT_ENCODING"=>"gzip, deflate", "HTTP_SEC_WEBSOCKET_VERSION"=>"13", "HTTP_ORIGIN"=>"http://localhost:3000", "HTTP_SEC_WEBSOCKET_KEY"=>"Gm5a5MOfEm8PLvIDWP9ZGg==", "HTTP_COOKIE"=>"_devtest_session=d578337f95828a1edf9c184715d0d483", "HTTP_CONNECTION"=>"keep-alive, Upgrade", "HTTP_PRAGMA"=>"no-cache", "HTTP_CACHE_CONTROL"=>"no-cache", "HTTP_UPGRADE"=>"websocket", "GATEWAY_INTERFACE"=>"CGI/1.2", "SERVER_PORT"=>"3000", "QUERY_STRING"=>"", "SERVER_PROTOCOL"=>"HTTP/1.1", "rack.url_scheme"=>"http", "SCRIPT_NAME"=>"", "em.connection"=>#<Thin::Connection:0x0000010360e560 @Signature=70, @request=#<Thin::Request:0x0000010360e330 @parser=#Thin::HttpParser:0x0000010360e308, @DaTa=nil, @nparsed=541, @Body=#StringIO:0x0000010360e1c8, @env={...}>, @response=#<Thin::Response:0x0000010360e150 @headers=, @status=101, @Persistent=true, @Body=#<Faye::WebSocket::Stream:0x000001030051a0 @web_socket=#<Faye::WebSocket:0x000001030051f0 ...>, @connection=#<Thin::Conne ...

About 77 MByte of text follow !

Unauthorized WebSocket connections can send messages that crash rails

In a web console, establish a WebSocket connection to your server (outside of your application), then send it a message:

var w = new WebSocket('ws://localhost:3000/websocket');
w.send('hello world');

Invalid Event Received: 757: unexpected token at 'hello world'
Exiting
/Users/wangstabill/.rvm/gems/ruby-1.9.3-head/bundler/gems/websocket-rails-8b9d4a32b680/lib/websocket_rails/dispatcher.rb:26:in dispatch': undefined methodname' for nil:NilClass (NoMethodError)
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/bundler/gems/websocket-rails-8b9d4a32b680/lib/websocket_rails/connection_adapters.rb:113:in dispatch' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/bundler/gems/websocket-rails-8b9d4a32b680/lib/websocket_rails/connection_adapters.rb:51:inon_message'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/bundler/gems/websocket-rails-8b9d4a32b680/lib/websocket_rails/connection_adapters/web_socket.rb:24:in on_message' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket/api/event_target.rb:24:incall'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket/api/event_target.rb:24:in dispatch_event' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket/api.rb:45:inreceive'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket/hybi_parser.rb:260:in emit_frame' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket/hybi_parser.rb:125:inparse'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket.rb:172:in parse' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/websocket.rb:202:inreceive'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/faye-websocket-0.4.6/lib/faye/adapters/thin.rb:46:in receive_data' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:inrun_machine'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in run' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/thin-1.5.0/lib/thin/backends/base.rb:63:instart'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/thin-1.5.0/lib/thin/server.rb:159:in start' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/rack-1.4.1/lib/rack/handler/thin.rb:13:inrun'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/rack-1.4.1/lib/rack/server.rb:265:in start' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.8/lib/rails/commands/server.rb:70:instart'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.8/lib/rails/commands.rb:55:in block in <top (required)>' from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.8/lib/rails/commands.rb:50:intap'
from /Users/wangstabill/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.8/lib/rails/commands.rb:50:in <top (required)>' from script/rails:6:inrequire'
from script/rails:6:in `

'

Websocket not being triggered in daemon

I have implemented a trigger to web socket in the Model of a rails app, it works perfectly when the function in the model is called via the application - when we use it through the browser.

But when I call the same function through a daemon or rails console, its not working.

How to handle disconnects?

Hi,

is there a way to handle disconnects on client side? I would like reconnect every 10 seconds if my client loses his connection.

Thanks
Mike

uninitialized constant WebsocketRails::InternalEvents::InternalController

First off, great gem, exactly what I was looking for.

Id like to use this on a production application but I am randomly getting:

uninitialized constant WebsocketRails::InternalEvents::InternalController

Error occured when loading the following file

.rvm/gems/ruby-1.9.3-p125/gems/websocket-rails-0.2.0/lib/rails/config/routes.rb

Any ideas whats going on? Im trying to use w/ redis in standalone mode, in development environment. The error seems to go away after refresh, and it happens more often when there are get params it seems in the request of the page.

Restore event/channel binding when re-connected an websocket

Once an websocket connection is disconnected, I'm trying to re-establish the connection and restore its event/channel bindings, like:

var dispatcher = new WebSocketRails(url);
dispatcher.bind('connection_closed', function() {
      window.dispatcher.state = 'connecting';
      refresh_dispatcher();
    });
dispatcher.bind('connection_error', function() {
      window.dispatcher.state = 'connecting';
      refresh_dispatcher();
    });
$(function(){
    $('body').bind('mouseenter', function(){ refresh_dispatcher(); });
    setTimeout(function(){ //  this is to ensure not to duplicate bindings
        for (var key in dispatcher.channels) {
            if (key)  return;
        }
        websocket_init(); // this function restores event/channel bindings
    }, 2000);
});
function refresh_dispatcher() {
    if (window.dispatcher.state != 'connected') {
        window.dispatcher = new WebSocketRails(window.dispatcher.url);
        websocket_init();   // this function restores event/channel bindings
    }
}

However, like jQuery's live() function, once the websocket connection is restored, I want to make it's event/channel bindings restored simultaneously.

This functionality is very useful when you use it with mobile environment.
Thanks!

Way to crash the server

I would like to set the title as an improvement, but I found a nasty bug.

Websockets support transfer binary files. I tried to do it with the gem, but I realized that it only supports json.

When you send a binary file to the server, Faye converts it to a byte array. Then in the event.rb:68 ( WebsocketRails::Event ) the resulting data passed to the function JSON.parse which throws exception no implicit conversion of Array into String (TypeError) and the server crashes.

P.S. Uploading a file I did with this article http://www.html5rocks.com/en/tutorials/websockets/basics/

group broadcasting

is there any way to restrict some messages to group of users, so this code
broadcast_message 'posted','my_post' will not send the content of the post to all users

i was thinking about creating private channels by accepting/rejecting channel subscription according to an action method defined by the programmer like this.

class EventController < WebsocketRails::BaseController
  def log_in
    data_store[:user] = current_user # getting current user from devise
    data_store[:discussion] = Discussion.find_by_id message[:discussion_id] # setting chat container id for this session
  end

  def subscribe
    if can? :update, data_store[:discussion]
      channel = message[:channel]
      #accept the subscription and push it to the channels array/hash 
      send_message 'websocket_rails.subscribed', channel
    else
      #reject 
      send_message 'websocket_rails.failed', channel
    end
  end
end

this requires overriding your default event mapping for  ``` websocket_rails.subscribe```

Can't Access Helpers in Websocket Controller

Hi,
i am trying to access devise helpers in WebSocket Controller, but it didn't work !

is it a bug , or i can't use helpers in WebSocket Controller ?

if i can't, how do i know session information for the user who opened the websocket ?

uninitialized constant WebsocketRails::InternalController

Hello,
I'm runnning 64Bit Archlinux, Ruby 1.9.3-p385, Rails 3.2.12, websockets-rails 0.4.2, thin 1.5.0. Quite often I encounter "uninitialized constant WebsocketRails::InternalController" error.

My error log:

I [2013-03-11 21:33:46.366] [ConnectionManager] Connection opened: #<Connnection::31444680>

I [2013-03-11 21:33:53.459] [Dispatcher] Started Event: app.roster.read
I [2013-03-11 21:33:53.460] [Dispatcher] Name: app.roster.read
I [2013-03-11 21:33:53.460] [Dispatcher] Data: {"a"=>1}
I [2013-03-11 21:33:53.460] [Dispatcher] Connection: #<Connnection::31444680>

E [2013-03-11 21:33:53.461] [Dispatcher] NameError: uninitialized constant WebsocketRails::InternalController
E [2013-03-11 21:33:53.461] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/controller_factory.rb:64:in `reload!'
E [2013-03-11 21:33:53.461] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/controller_factory.rb:15:in `new_for_event'
E [2013-03-11 21:33:53.461] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/dispatcher.rb:52:in `block (3 levels) in route'
E [2013-03-11 21:33:53.461] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/logging.rb:60:in `call'
E [2013-03-11 21:33:53.461] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/logging.rb:60:in `log_event'
E [2013-03-11 21:33:53.462] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/dispatcher.rb:51:in `block (2 levels) in route'

E [2013-03-11 21:33:56.440] [Dispatcher] NameError: uninitialized constant WebsocketRails::InternalController
E [2013-03-11 21:33:56.441] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/controller_factory.rb:64:in `reload!'
E [2013-03-11 21:33:56.441] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/controller_factory.rb:15:in `new_for_event'
E [2013-03-11 21:33:56.441] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/dispatcher.rb:52:in `block (3 levels) in route'
E [2013-03-11 21:33:56.441] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/logging.rb:60:in `call'
E [2013-03-11 21:33:56.441] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/logging.rb:60:in `log_event'
E [2013-03-11 21:33:56.441] [Dispatcher] /home/cinan/.rvm/gems/ruby-1.9.3-p385/gems/websocket-rails-0.4.2/lib/websocket_rails/dispatcher.rb:51:in `block (2 levels) in route'

I [2013-03-11 21:34:06.446] [ConnectionManager] Connection closed: #<Connnection::31444680>

I [2013-03-11 21:34:46.559] [ConnectionManager] Connection closed: #<Connnection::31444680>

A strange thing is the connection is opened once but closed twice (any intercation from a client). No responce from server comes to a client (for example if controller method returns trigger_success message: "ok" a client doesn't receive it).

I noticed the error occurs always when I change controller's source code. After each change I have to restart thin server, which is very annoying.

Can't use with passenger

I'm using Ruby 1.9.2

I've just made a scaffold with two parameter title and body
followed the install instructions

Running with thin works.
Running with passenger gives the stack..

RuntimeError (eventmachine not initialized: evma_install_oneshot_timer):
eventmachine (0.12.10) lib/eventmachine.rb:375:in add_oneshot_timer' eventmachine (0.12.10) lib/eventmachine.rb:375:inadd_timer'
eventmachine (0.12.10) lib/em/timers.rb:47:in schedule' eventmachine (0.12.10) lib/em/timers.rb:35:ininitialize'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:124:in new' websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:124:instart_ping_timer'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:40:in initialize' websocket-rails (0.1.8) lib/websocket_rails/connection_adapters/web_socket.rb:10:ininitialize'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:14:in new' websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:14:inestablish_connection'
websocket-rails (0.1.8) lib/websocket_rails/connection_manager.rb:59:in open_connection' websocket-rails (0.1.8) lib/websocket_rails/connection_manager.rb:36:incall'
journey (1.0.4) lib/journey/router.rb:68:in block in call' journey (1.0.4) lib/journey/router.rb:56:ineach'
journey (1.0.4) lib/journey/router.rb:56:in call' actionpack (3.2.2) lib/action_dispatch/routing/route_set.rb:594:incall'
actionpack (3.2.2) lib/action_dispatch/middleware/best_standards_support.rb:17:in call' rack (1.4.1) lib/rack/etag.rb:23:incall'
rack (1.4.1) lib/rack/conditionalget.rb:25:in call' actionpack (3.2.2) lib/action_dispatch/middleware/head.rb:14:incall'
actionpack (3.2.2) lib/action_dispatch/middleware/params_parser.rb:21:in call' actionpack (3.2.2) lib/action_dispatch/middleware/flash.rb:242:incall'
rack (1.4.1) lib/rack/session/abstract/id.rb:205:in context' rack (1.4.1) lib/rack/session/abstract/id.rb:200:incall'
actionpack (3.2.2) lib/action_dispatch/middleware/cookies.rb:338:in call' activerecord (3.2.2) lib/active_record/query_cache.rb:64:incall'
activerecord (3.2.2) lib/active_record/connection_adapters/abstract/connection_pool.rb:443:in call' actionpack (3.2.2) lib/action_dispatch/middleware/callbacks.rb:28:inblock in call'
activesupport (3.2.2) lib/active_support/callbacks.rb:405:in _run__607216680103759680__call__3159158661904658260__callbacks' activesupport (3.2.2) lib/active_support/callbacks.rb:405:in__run_callback'
activesupport (3.2.2) lib/active_support/callbacks.rb:385:in _run_call_callbacks' activesupport (3.2.2) lib/active_support/callbacks.rb:81:inrun_callbacks'
actionpack (3.2.2) lib/action_dispatch/middleware/callbacks.rb:27:in call' actionpack (3.2.2) lib/action_dispatch/middleware/remote_ip.rb:31:incall'
actionpack (3.2.2) lib/action_dispatch/middleware/debug_exceptions.rb:16:in call' actionpack (3.2.2) lib/action_dispatch/middleware/show_exceptions.rb:56:incall'
railties (3.2.2) lib/rails/rack/logger.rb:26:in call_app' railties (3.2.2) lib/rails/rack/logger.rb:16:incall'
actionpack (3.2.2) lib/action_dispatch/middleware/request_id.rb:22:in call' rack (1.4.1) lib/rack/methodoverride.rb:21:incall'
rack (1.4.1) lib/rack/runtime.rb:17:in call' activesupport (3.2.2) lib/active_support/cache/strategy/local_cache.rb:72:incall'
actionpack (3.2.2) lib/action_dispatch/middleware/static.rb:61:in call' railties (3.2.2) lib/rails/engine.rb:479:incall'
railties (3.2.2) lib/rails/application.rb:220:in call' railties (3.2.2) lib/rails/railtie/configurable.rb:30:inmethod_missing'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/rack/request_handler.rb:96:in process_request' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_request_handler.rb:513:inaccept_and_process_next_request'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_request_handler.rb:274:in main_loop' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:206:instart_request_handler'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:171:in block in handle_spawn_application' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/utils.rb:479:insafe_fork'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:166:in handle_spawn_application' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:357:inserver_main_loop'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:206:in start_synchronously' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:180:instart'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/rack/application_spawner.rb:129:in start' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:253:inblock (2 levels) in spawn_rack_application'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server_collection.rb:132:in lookup_or_add' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:246:inblock in spawn_rack_application'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server_collection.rb:82:in block in synchronize' <internal:prelude>:10:insynchronize'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server_collection.rb:79:in synchronize' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:244:inspawn_rack_application'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:137:in spawn_application' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/spawn_manager.rb:275:inhandle_spawn_application'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:357:in server_main_loop' /Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/lib/phusion_passenger/abstract_server.rb:206:instart_synchronously'
/Users/luiz/.passenger/standalone/3.0.12-x86_64-ruby1.9.2-macosx-10.6/support/helper-scripts/passenger-spawn-server:99:in `

'

Rendered /Users/luiz/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/_trace.erb (4.3ms)
Rendered /Users/luiz/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (1.4ms)
Rendered /Users/luiz/.rvm/gems/ruby-1.9.2-p290/gems/actionpack-3.2.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (29.3ms)

Ruby 1.8.7 Compatibility

I have ruby 1.8.7 (2011-12-28 patchlevel 357) [universal-darwin11.0] using Rails 3.2.6. I got this message, when i try to do any action inside of my rails application:

Fabian-iMac:rails framirez$ rails s
/Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `require': /Library/Ruby/Gems/1.8/gems/websocket-rails-0.1.8/lib/websocket_rails/data_store.rb:68: undefined (?...) sequence: /each_(?<hash_key>\w*)/ (SyntaxError)
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `require'
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:236:in `load_dependency'
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `require'
    from /Library/Ruby/Gems/1.8/gems/websocket-rails-0.1.8/lib/websocket_rails/base_controller.rb:1
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `require'
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `require'
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:236:in `load_dependency'
    from /Library/Ruby/Gems/1.8/gems/activesupport-3.2.6/lib/active_support/dependencies.rb:251:in `require'
    from /Library/Ruby/Gems/1.8/gems/websocket-rails-0.1.8/lib/websocket-rails.rb:31
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler/runtime.rb:68:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler/runtime.rb:68:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler/runtime.rb:66:in `each'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler/runtime.rb:66:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler/runtime.rb:55:in `each'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler/runtime.rb:55:in `require'
    from /Library/Ruby/Gems/1.8/gems/bundler-1.1.4/lib/bundler.rb:119:in `require'
    from /Users/framirez/Work/fxts/rails/config/application.rb:7
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.6/lib/rails/commands.rb:53:in `require'
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.6/lib/rails/commands.rb:53
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.6/lib/rails/commands.rb:50:in `tap'
    from /Library/Ruby/Gems/1.8/gems/railties-3.2.6/lib/rails/commands.rb:50
    from script/rails:6:in `require'
    from script/rails:6

I fixed it commenting these lines above:

    def method_missing(method, *args, &block)
#      if /each_(?<hash_key>\w*)/ =~ method
#        results = []
#        @data.each do |cid,hash|
#          results << hash[hash_key]
#        end
#        results
#      else
        super
#      end
    end

Please check it, and fix it or tell me how fix it.

Authorization without devise and cancan

  1. In our project we have simple authorization through session which contain user_id, token_number and token_id. Checking user auth with only token_number is not safely. Now we put session object on page javascript as hash and post them to websocket server. This way is absolutely unsafe. Is it possible to get the data from the session in a different way? I have tried to understand how it works in devise, but it was without results.
  2. In rails application we have controller auth with before filter that redirect to login page if user has not valid session. Can I organize similar functionality in websockets controllers? For example, close connection instead of redirect.

P.S. sorry for my english...

Ideas for scaling

Hi all,

currently im running one thin with websockets and I think in some weeks we need to add additional webservers to handle our load. I've no idea how to scale the websockets part because the websocket-controller is bound to one process. Same issue using unicorn or other multi-worker systems because this controller is bound to one worker and they can't communicate with each other.

One way would be adding a pubsub pattern with zero-mq or something similar but this is just an idea.

Any other ideas?

Thanks
Mike

Firefox/Streaming HTTP

I'm trying to get it to work with either websockets or streaming http. This is the error I'm getting on the server:

Application Exception: #<NoMethodError: undefined method `[]=' for nil:NilClass>

on the client i'm getting an 'invalid' response, but I suspect it's because of the server.

It happens when I first try to send a message from the client to the server. Specifically a 'hello' message from the client to the server. All of this works fine in Chrome, but does not in Firefox or Safari. I'm not sure if I'm doing something wrong or if this is a genuine bug.

Here's a bunch of code to help:

EventMap

WebsocketRails::EventMap.describe do
  subscribe :client_connected, to: ClientController, with_method: :client_connected
  subscribe :hello, to: ClientController, with_method: :on_hello_message
  subscribe :move, to: ClientController, with_method: :on_player_move
  #subscribe :new_user, to: ClientController, with_method: :new_user
  #subscribe :change_username, to: ClientController, with_method: :change_username
  subscribe :client_disconnected, to: ClientController, with_method: :client_disconnected
end

Controller

class ClientController < WebsocketRails::BaseController

  def client_connected
    Rails.logger.debug 'client connected'
  end

  def on_hello_message
    Rails.logger.debug message

    facebook_id = message["facebook_id"]
    user = User.find_by_facebook_id("#{facebook_id}")
    if(user.nil?)
      user = User.new({:facebook_id => facebook_id.to_i})
    end

    send_message :welcome, {:player_id => "#{user.facebook_id}"}
    data_store[client_id] = user
    broadcast_message :spawn, {:player_id => "#{user.facebook_id}", :x => user.position_x, :y => user.position_y}
  end

  def on_player_move
    user = data_store[client_id]
    x = message["x"]
    y = message["y"]
    user.position_x = x
    user.position_y = y
    broadcast_message :move, {:player_id => "#{user.facebook_id}", :x => x, :y => y}
  end

  def client_disconnected
    user = data_store[client_id]
    Rails.logger.debug "client disconnected #{user.facebook_id}"
    @logged_in[user.facebook_id] = nil
  end

end

Client JS

    connected_callback: function(){
        // TODO: Get the Player Facebook ID from the browser via the browser login
        console.log('TODO: get facebook id from browser')
        jsApp.gameClient.player_info = {'facebook_id': '9287477388887'};
        jsApp.gameClient.sendHello(jsApp.gameClient.player_info);
    },


    sendHello: function(player) {
        this.sendMessage('hello',
                {'facebook_id':player.facebook_id});
    },

    sendMessage: function(event_name, json) {
        this.dispatcher.trigger(event_name, json);
    },

GIT
  remote: https://github.com/DanKnox/websocket-rails.git
  revision: dc7d375ff65be8f2c9f095e97331f970157a4be9
  specs:
    websocket-rails (0.1.5)
      faye-websocket
      rack
      rails
      thin

PATH
  remote: ~/lib/neology
  specs:
    neology (0.0.1)
      activesupport
      neography (~> 0.0.22)

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (3.2.0)
      actionpack (= 3.2.0)
      mail (~> 2.4.0)
    actionpack (3.2.0)
      activemodel (= 3.2.0)
      activesupport (= 3.2.0)
      builder (~> 3.0.0)
      erubis (~> 2.7.0)
      journey (~> 1.0.0)
      rack (~> 1.4.0)
      rack-cache (~> 1.1)
      rack-test (~> 0.6.1)
      sprockets (~> 2.1.2)
    activemodel (3.2.0)
      activesupport (= 3.2.0)
      builder (~> 3.0.0)
    activerecord (3.2.0)
      activemodel (= 3.2.0)
      activesupport (= 3.2.0)
      arel (~> 3.0.0)
      tzinfo (~> 0.3.29)
    activeresource (3.2.0)
      activemodel (= 3.2.0)
      activesupport (= 3.2.0)
    activesupport (3.2.0)
      i18n (~> 0.6)
      multi_json (~> 1.0)
    addressable (2.2.8)
    arel (3.0.2)
    builder (3.0.0)
    coffee-rails (3.2.2)
      coffee-script (>= 2.2.0)
      railties (~> 3.2.0)
    coffee-script (2.2.0)
      coffee-script-source
      execjs
    coffee-script-source (1.3.3)
    cookiejar (0.3.0)
    daemons (1.1.8)
    diff-lcs (1.1.3)
    em-http-request (0.3.0)
      addressable (>= 2.0.0)
      escape_utils
      eventmachine (>= 0.12.9)
    erubis (2.7.0)
    escape_utils (0.2.4)
    eventmachine (0.12.10)
    execjs (1.4.0)
      multi_json (~> 1.0)
    faye (0.8.3)
      cookiejar (>= 0.3.0)
      em-http-request (>= 0.3.0)
      eventmachine (>= 0.12.0)
      faye-websocket (>= 0.4.0)
      rack (>= 1.0.0)
      yajl-ruby (>= 1.0.0)
    faye-websocket (0.4.6)
      eventmachine (>= 0.12.0)
    hike (1.2.1)
    httparty (0.8.3)
      multi_json (~> 1.0)
      multi_xml
    i18n (0.6.0)
    journey (1.0.4)
    jquery-rails (2.0.2)
      railties (>= 3.2.0, < 5.0)
      thor (~> 0.14)
    json (1.7.3)
    libv8 (3.3.10.4)
    mail (2.4.4)
      i18n (>= 0.4.0)
      mime-types (~> 1.16)
      treetop (~> 1.4.8)
    mime-types (1.19)
    multi_json (1.3.6)
    multi_xml (0.5.1)
    neography (0.0.27)
      httparty (>= 0.8.1)
      json
      oj
      os
      rake (>= 0.8.7)
      rubyzip
    oj (1.3.0)
    os (0.9.6)
    polyglot (0.3.3)
    rack (1.4.1)
    rack-cache (1.2)
      rack (>= 0.4)
    rack-ssl (1.3.2)
      rack
    rack-test (0.6.1)
      rack (>= 1.0)
    rails (3.2.0)
      actionmailer (= 3.2.0)
      actionpack (= 3.2.0)
      activerecord (= 3.2.0)
      activeresource (= 3.2.0)
      activesupport (= 3.2.0)
      bundler (~> 1.0)
      railties (= 3.2.0)
    railties (3.2.0)
      actionpack (= 3.2.0)
      activesupport (= 3.2.0)
      rack-ssl (~> 1.3.2)
      rake (>= 0.8.7)
      rdoc (~> 3.4)
      thor (~> 0.14.6)
    rake (0.9.2.2)
    rdoc (3.12)
      json (~> 1.4)
    rspec (2.11.0)
      rspec-core (~> 2.11.0)
      rspec-expectations (~> 2.11.0)
      rspec-mocks (~> 2.11.0)
    rspec-core (2.11.0)
    rspec-expectations (2.11.1)
      diff-lcs (~> 1.1.3)
    rspec-mocks (2.11.1)
    rspec-rails (2.11.0)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      railties (>= 3.0)
      rspec (~> 2.11.0)
    rubyzip (0.9.9)
    sass (3.1.20)
    sass-rails (3.2.5)
      railties (~> 3.2.0)
      sass (>= 3.1.10)
      tilt (~> 1.3)
    sprockets (2.1.3)
      hike (~> 1.2)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    therubyracer (0.10.1)
      libv8 (~> 3.3.10)
    thin (1.4.1)
      daemons (>= 1.0.9)
      eventmachine (>= 0.12.6)
      rack (>= 1.0.0)
    thor (0.14.6)
    tilt (1.3.3)
    treetop (1.4.10)
      polyglot
      polyglot (>= 0.3.1)
    tzinfo (0.3.33)
    uglifier (1.2.6)
      execjs (>= 0.3.0)
      multi_json (~> 1.3)
    yajl-ruby (1.1.0)

PLATFORMS
  ruby

DEPENDENCIES
  coffee-rails (~> 3.2.1)
  faye
  jquery-rails
  json
  neography
  neology!
  rails (= 3.2.0)
  rspec-rails (~> 2.0)
  sass-rails (~> 3.2.3)
  therubyracer
  thin
  uglifier (>= 1.0.3)
  websocket-rails!

Production config with thin a/o nginx/proxy

Hi there,

does someone using nginx as a production webserver and thin behind it?

Currently there is no support for HTTP 1.1 connections in nginx and I'm struggeling setting up a production env.

@DanKnox what are you using for your production setup?

Thanks
Mike

Warden, websockets and fiber pool

I am unable to get the three to play nicely in a stand alone env.

If I put fiber pool before warden the websocket server doesn't work and gives the following exception:

fiber called across threads

rack-fiber_pool (0.9.2) lib/fiber_pool.rb:75:in `resume'
rack-fiber_pool (0.9.2) lib/fiber_pool.rb:75:in `spawn'
rack-fiber_pool (0.9.2) lib/rack/fiber_pool.rb:28:in `call'
rack (1.4.3) lib/rack/etag.rb:23:in `call'
rack (1.4.3) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/head.rb:14:in `call'
remotipart (1.0.2) lib/remotipart/middleware.rb:30:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.3) lib/rack/session/abstract/id.rb:210:in `context'
rack (1.4.3) lib/rack/session/abstract/id.rb:205:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/cookies.rb:341:in `call'
activerecord (3.2.11) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.11) lib/active_record/connection_adapters/abstract/connection_pool.rb:479:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `_run__4388855720588063737__call__4389336017110659463__callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.11) lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
activesupport (3.2.11) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.11) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.11) lib/rails/rack/logger.rb:32:in `call_app'
railties (3.2.11) lib/rails/rack/logger.rb:16:in `block in call'
activesupport (3.2.11) lib/active_support/tagged_logging.rb:22:in `tagged'
railties (3.2.11) lib/rails/rack/logger.rb:16:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.3) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.3) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.11) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
actionpack (3.2.11) lib/action_dispatch/middleware/static.rb:62:in `call'
railties (3.2.11) lib/rails/engine.rb:479:in `call'
railties (3.2.11) lib/rails/application.rb:223:in `call'
railties (3.2.11) lib/rails/railtie/configurable.rb:30:in `method_missing'
thin (1.5.0) lib/thin/connection.rb:81:in `block in pre_process'
thin (1.5.0) lib/thin/connection.rb:79:in `catch'
thin (1.5.0) lib/thin/connection.rb:79:in `pre_process'
eventmachine (1.0.0) lib/eventmachine.rb:1037:in `call'
eventmachine (1.0.0) lib/eventmachine.rb:1037:in `block in spawn_threadpool'

But if I put it after Warden I am unable to login and get an uncaught throw `warden' upon being redirected after login.

How to authenticate any new websocket connection?

Hi,
I'm writing chat app; after successful sign in (no websocket here, just classic login form) users are redirected to chatting page. Right after loading the page websocket connection is started. The question is, how can I tell which user is trying to communicate with server (when websocket connection is opened)?
Users are authenticated through tokens; since websocket controllers are not ActionController::Base controllers I can't access session variable.

Thanks

Bug in sync in the latest versions

I have 2 computers with their thin servers. On one of them works redis through which they are synchronized. Prior to version 4 all worked fine but now I get the error when channels synchronized:

`trigger_event ': Called id for nil ...

It occurs in the file channel.rb 35 line.

If you look above, the event is formed by a method Event.new_from_json (encoded_event, nil) where the nil is connection. That's the problem.

I don't quite understand how it would work but if you remove event.connection.id from log then everything works fine. Like this:

From

 def trigger_event(event)
      info "(processing_channel_event) name: #{event.name} namespace: #{event.namespace} connection: #{event.connection.id}"
      send_data event
    end

To

 def trigger_event(event)
      info "(processing_channel_event) name: #{event.name} namespace: #{event.namespace}"
      send_data event
    end

uninitialized constant ThreadPostsController::WebSocketRails

i am trying to use the channel feature, and i'm using this code in my Regular Rails Controller

  # POST /thread_posts
  # POST /thread_posts.json
  def create
    @discussion = Discussion.find_by_id params[:discussion_id]
    @thread_post = @discussion.thread_posts.new
    @thread_post.body = params[:body]
    @thread_post.user_id = current_user.id
    respond_to do |format|
      if @thread_post.save
        WebSocketRails[:posts].trigger('posted',:id => @thread_post.id);
        format.html { redirect_to @thread_post, notice: 'Thread post was successfully created.' }
        format.json { render json: @thread_post, status: :created, location: @thread_post }
      else
        format.html { render action: "new" }
        format.json { render json: @thread_post.errors, status: :unprocessable_entity }
      end
    end
  end

it gives the following error

uninitialized constant ThreadPostsController::WebSocketRails

is there any initialization code to write ?

Synchronization not working from background process

Even when running the rails server using thin without standalone mode enabled, synchronization seems to not be working for me. Ive tried triggering events from sidekiq workers as well as directly from the console, and I get the same error in both instances:

RuntimeError: eventmachine not initialized: evma_connect_to_server
from /Users/jayre/.rvm/gems/ruby-1.9.2-p320/gems/eventmachine-1.0.0/lib/eventmachine.rb:664:in `connect_server'

Any ideas?

undefined method send for nil class crashes the server

/Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/websocket-rails-0.4.3/lib/websocket_rails/connection_adapters/web_socket.rb:19:in send': undefined method[["websocket_rails.ping",{"id":null,"channel":null,"data":{},"success":null,"result":null,"server_token":null}]]' for nil:NilClass (NoMethodError)
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/websocket-rails-0.4.3/lib/websocket_rails/connection_adapters.rb:80:in trigger' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/websocket-rails-0.4.3/lib/websocket_rails/connection_adapters.rb:140:inblock in start_ping_timer'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0/lib/em/timers.rb:56:in call' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0/lib/em/timers.rb:56:infire'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in call' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:inrun_machine'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/eventmachine-1.0.0/lib/eventmachine.rb:187:in run' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/thin-1.5.1/lib/thin/backends/base.rb:63:instart'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/thin-1.5.1/lib/thin/server.rb:159:in start' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/thin-1.5.1/lib/thin/controllers/controller.rb:86:instart'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/thin-1.5.1/lib/thin/runner.rb:187:in run_command' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/thin-1.5.1/lib/thin/runner.rb:152:inrun!'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/gems/thin-1.5.1/bin/thin:6:in <top (required)>' from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/bin/thin:19:inload'
from /Users/roxxypoxxy/.rvm/gems/ruby-1.9.3-p0/bin/thin:19:in `

'

uninitialized constant WebsocketRails::ConnectionAdapters::Base::DelegationController

When attempting to establish a new websocket connection, I'm seeing this error:

uninitialized constant WebsocketRails::ConnectionAdapters::Base::DelegationController

I followed the installation guide from the github page. Here's my gemlist:


Using rake (0.9.2.2) 
Using Ascii85 (1.0.1) 
Using i18n (0.6.0) 
Using multi_json (1.3.6) 
Using activesupport (3.2.6) 
Using builder (3.0.0) 
Using activemodel (3.2.6) 
Using erubis (2.7.0) 
Using journey (1.0.4) 
Using rack (1.4.1) 
Using rack-cache (1.2) 
Using rack-test (0.6.1) 
Using hike (1.2.1) 
Using tilt (1.3.3) 
Using sprockets (2.1.3) 
Using actionpack (3.2.6) 
Using mime-types (1.19) 
Using polyglot (0.3.3) 
Using treetop (1.4.10) 
Using mail (2.4.4) 
Using actionmailer (3.2.6) 
Using ruby-ldap (0.9.12) 
Using active_ldap (3.1.1) from git://github.com/Mochaleaf/activeldap.git (at master) 
Using arel (3.0.2) 
Using tzinfo (0.3.33) 
Using activerecord (3.2.6) 
Using activeresource (3.2.6) 
Using addressable (2.2.8) 
Using ansi (1.4.3) 
Using beanstalk-client (1.1.1) 
Using chunky_png (1.2.5) 
Using cocaine (0.2.1) 
Using coderay (1.0.7) 
Using coffee-script-source (1.3.3) 
Using execjs (1.4.0) 
Using coffee-script (2.2.0) 
Using fssm (0.2.9) 
Using sass (3.1.20) 
Using compass (0.12.2) 
Using compass-rails (1.0.3) 
Using daemons (1.1.8) 
Using database_cleaner (0.8.0) 
Using diff-lcs (1.1.3) 
Using eventmachine (0.12.10) 
Using fattr (2.2.1) 
Using faye-websocket (0.4.6) 
Using ffi (1.0.11) 
Using rb-appscript (0.6.1) 
Using growl_notify (0.0.3) 
Using rb-fchange (0.0.5) 
Using rb-fsevent (0.9.1) 
Using rb-inotify (0.8.8) 
Using listen (0.4.7) 
Using thor (0.15.4) 
Using guard (1.2.3) 
Using guard-rspec (1.2.0) 
Using spork (0.9.2) 
Using guard-spork (1.1.0) 
Using haml (3.1.6) 
Using highline (1.6.13) 
Using rack-ssl (1.3.2) 
Using json (1.7.3) 
Using rdoc (3.12) 
Using railties (3.2.6) 
Using jquery-rails (2.0.2) 
Using launchy (2.1.0) 
Using systemu (2.5.1) 
Using macaddr (1.6.1) 
Using method_source (0.7.1) 
Using mysql2 (0.3.11) 
Using net-ldap (0.3.1) 
Using nokogiri (1.5.5) 
Using options (2.3.0) 
Using paperclip (3.1.2) 
Using ruby-rc4 (0.1.5) 
Using pdf-reader (1.1.1) 
Using pr_geohash (1.0.0) 
Using ttfunk (1.0.3) 
Using prawn (1.0.0.rc1) from git://github.com/sandal/prawn.git (at master) 
Using progress_bar (0.4.0) 
Using slop (2.4.4) 
Using pry (0.9.9.6) 
Using rb-readline (0.4.2) 
Using ruby-termios (0.9.6) 
Using pry-remote-em (0.6.3) 
Using railroady (1.0.8) 
Using bundler (1.1.4) 
Using rails (3.2.6) 
Using rmagick (2.13.1) 
Using rqrcode (0.4.2) 
Using rsolr (1.0.8) 
Using rspec-core (2.11.0) 
Using rspec-expectations (2.11.1) 
Using rspec-mocks (2.11.1) 
Using rspec (2.11.0) 
Using rspec-rails (2.11.0) 
Using sass-rails (3.2.5) 
Using simplecov-html (0.5.3) 
Using simplecov (0.6.4) 
Using sunspot (1.3.3) 
Using sunspot_rails (1.3.3) 
Using sunspot_solr (1.3.3) 
Using thin (1.4.1) 
Using turn (0.9.6) 
Using uglifier (1.2.6) 
Using uuid (2.3.5) 
Using websocket-rails (0.1.5) 

Yet more passenger woes

I got everything working locally great, tried it using webrick and passenger-standalone as the rails server, while running the standalone server. After pushing to staging server, using the actual passenger gem, when I try to run rake websocket_rails:start_server it never starts and throws the following error in the log. (also tried bundle exec rake websocket_rails:start_server but get same error)

from /var/www/app_name/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:110:in `run_with_threads'
from /var/www/app_name/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:95:in `top_level'
from /var/www/app_name/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:73:in `block in run'
from /var/www/app_name/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:160:in `standard_exception_handling'
from /var/www/app_name/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/lib/rake/application.rb:70:in `run'
from /var/www/app_name/shared/bundle/ruby/1.9.1/gems/rake-10.0.3/bin/rake:33:in `<top (required)>'
from /usr/local/rvm/gems/ruby-1.9.3-p327/bin/rake:19:in `load'
from /usr/local/rvm/gems/ruby-1.9.3-p327/bin/rake:19:in `<main>'
from /usr/local/rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `eval'
from /usr/local/rvm/gems/ruby-1.9.3-p327/bin/ruby_noexec_wrapper:14:in `<main>'

Ive checked to make sure threadsafe is enabled for staging server, etc. Not sure what the dillio is now, any ideas?

Thanks

installOneshotTimer called on nil when using puma with Rails 3.2.7 on JRuby 1.6.7.2

Hello, when using puma as the Rails server for version 3.2.7 of Rails running on JRuby 1.6.7.2 (in 1.9 mode), I get the following error when a client tries to initiate a websocket connection:

NoMethodError (undefined method `installOneshotTimer' for nil:NilClass):
eventmachine-0.12.10 (java) lib/jeventmachine.rb:98:in `add_oneshot_timer'
eventmachine-0.12.10 (java) lib/eventmachine.rb:375:in `add_timer'
eventmachine-0.12.10 (java) lib/em/timers.rb:47:in `schedule'
eventmachine-0.12.10 (java) lib/em/timers.rb:35:in `initialize'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:124:in `start_ping_timer'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:40:in `initialize'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters/web_socket.rb:10:in `initialize'
websocket-rails (0.1.8) lib/websocket_rails/connection_adapters.rb:14:in `establish_connection'
websocket-rails (0.1.8) lib/websocket_rails/connection_manager.rb:59:in `open_connection'
websocket-rails (0.1.8) lib/websocket_rails/connection_manager.rb:36:in `call'
journey (1.0.4) lib/journey/router.rb:68:in `call'
org/jruby/RubyArray.java:1615:in `each'
journey (1.0.4) lib/journey/router.rb:56:in `call'
actionpack (3.2.7) lib/action_dispatch/routing/route_set.rb:600:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
rack (1.4.1) lib/rack/etag.rb:23:in `call'
rack (1.4.1) lib/rack/conditionalget.rb:25:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/head.rb:14:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/flash.rb:242:in `call'
rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'
rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/cookies.rb:338:in `call'
activerecord (3.2.7) lib/active_record/query_cache.rb:64:in `call'
activerecord (3.2.7) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/callbacks.rb:28:in `call'
activesupport (3.2.7) lib/active_support/callbacks.rb:408:in `_run__1848769036__call__806641318__callbacks'
org/jruby/RubyBasicObject.java:1698:in `__send__'
org/jruby/RubyKernel.java:2097:in `send'
activesupport (3.2.7) lib/active_support/callbacks.rb:405:in `__run_callback'
activesupport (3.2.7) lib/active_support/callbacks.rb:390:in `_run_call_callbacks'
org/jruby/RubyBasicObject.java:1698:in `__send__'
org/jruby/RubyKernel.java:2097:in `send'
activesupport (3.2.7) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (3.2.7) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/reloader.rb:65:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
railties (3.2.7) lib/rails/rack/logger.rb:26:in `call_app'
railties (3.2.7) lib/rails/rack/logger.rb:16:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/request_id.rb:22:in `call'
rack (1.4.1) lib/rack/methodoverride.rb:21:in `call'
rack (1.4.1) lib/rack/runtime.rb:17:in `call'
activesupport (3.2.7) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.4.1) lib/rack/lock.rb:15:in `call'
actionpack (3.2.7) lib/action_dispatch/middleware/static.rb:62:in `call'
railties (3.2.7) lib/rails/engine.rb:479:in `call'
railties (3.2.7) lib/rails/application.rb:220:in `call'
rack (1.4.1) lib/rack/content_length.rb:14:in `call'
railties (3.2.7) lib/rails/rack/log_tailer.rb:17:in `call'
puma-1.6.1 (java) lib/puma/server.rb:410:in `handle_request'
puma-1.6.1 (java) lib/puma/server.rb:304:in `process_client'
puma-1.6.1 (java) lib/puma/server.rb:215:in `run'
org/jruby/RubyProc.java:258:in `call'
puma-1.6.1 (java) lib/puma/thread_pool.rb:94:in `spawn_thread'

Please note that the Rails environment gets initialized without issue and can serve up normal pages just fine. This error only gets triggered when a browser tries to connect using websockets. Also note that this only happens with puma as I have had no trouble when using thin.

Since this happens with puma, I worry what would happen if I packaged my app up with warbler and tried to deploy it.

I stand ready to provide other diagnostic information if I can. Thanks!

Standalone mode SSL support

So after digging around the code after trying to get it running using ssl, Im guessing this isn't supported, I saw you at least considered SSL because I can pass the wss:// full url in the JS connection, but I'm guessing that isn't for standalone mode (because it looks like it needs to be specified in the thin configuration.)

When attempting to connect to secure socket server via wss I get

!! Invalid request

In log file. I'm assuming because SSL isn't supported w/ standalone, unless I am missing something?

Cached "session" variable in Controller?

In my single page application WebSockets used for live update customer orders when manager change it (add/del product, change date delivery... )

After creation order client subscribe to private channel with name "order.id" (i listen Backbone.Collection 'sync' event)

My autorizations method looks like:

class EventsController < WebsocketRails::BaseController
  def authorize_channels
    message_error = {message: "error"}
    order = Order.find message[:channel]

    if customer_session.can_show_order? order
      accept_channel
    else
      deny_channel message_error
    end
  end
...
end

customer_session helper:

def customer_session
    @customer_session ||= CustomerSession.new(session)
end

and class:

class CustomerSession
  def initialize(session)
    @session = session
    @session[:order_ids] ||= []
  end

  ...

  def can_show_order?(order)
    @session[:order_ids].include?(order.id)
  end
end

I can't autorize channel in current websocket connection. I have to reload location to subscribe channel.

Help me please. Thanks :)

One-way secured channels

Not sure if this is a feature request or me not being able to figure it out. The setup I'd like to have is:

User A sends messages on channel X to any other user on channel X. User A is the only person authorized to send messages on X. Other users can only listen.

Think of a Blogging application, where an author has a blog, and they make posts, and anyone can read. But the readers can't make posts.

As I understand websocket-rails, there would be an event the blogger sends called "publish", then the server could send an event down the blog's channel "blog-47" called "new_post". But I can't figure out how to stop anyone from publishing on "blog-47" events under "new_post".

If I make "blog-47" a private channel, that just manages subscriptions, but not triggering permission.

Thanks

Heroku Support: WebsocketRails as a Service

Hi DanKnox,
I use weboscket-rails in my app and it run evey well in localhost,but it can't be run heroku.
The connection established ,but can't send or receive message.How can I solve this problem?
My js code is

var dispatcher = new WebSocketRails('localhost:3000/websocket');

dispatcher.on_open = function(data) {
    console.log('Connection has been established: ');
    console.log(dispatcher)
}
$('.submit-mess').click(function(){
    if ($('#content').val().replace(/\s+/, "") == ""){
        return ;
    }
    params= {};
    params.content = $('#content').val();
    params.slug = $('#slug').val()
    dispatcher.trigger('new_message',params);


});

dispatcher.bind('new_message', function(content) {
    $('#content').val("");
    $('.message-list').prepend(content).show('slow');
});

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.