jimsynz / faye-rails

Simple Rails glue for the Faye messaging protocol.
MIT License
435 stars 79 forks source link

callback.call(message) extension problem #74

Open toomus opened 9 years ago

toomus commented 9 years ago

I have problem with callback.call(message). First my code:

application.rb

    config.middleware.delete Rack::Lock
    config.middleware.use FayeRails::Middleware, mount: '/faye', :timeout => 25 do
      map '/realtime_events/*' => RealtimeEventsController
      map :default => :block

      add_extension(RealtimeAuth.new)
    end

realtime_auth.rb

class RealtimeAuth
  def incoming(message, callback)
    puts "---- INCOMING ----"
    puts message.inspect
    if message['channel'] == '/meta/subscribe'
      puts "SUBSCRIBE CHANNEL"
      # my authentication logic
    else
      puts "OTHER CHANNEL"
      callback.call(message)
    end
  end

  def outgoing(message, callback)
    puts "---- OUTGOING ----"
    puts message.inspect
    callback.call(message)
  end
end

Whe i try to publish message to realtime_events channel i got this:

---- INCOMING ----
{"channel"=>"/realtime_events/2", "data"=>{:type=>"chat_invitation", :thread_id=>4, :sender_id=>13, :sender_name=>"johnny"}, "clientId"=>"dh3gi504ylm9z72otofwnv6fqpsr55c", "id"=>"2"}
OTHER CHANNEL

---- OUTGOING ----
{"id"=>"2", "channel"=>"/realtime_events/2", "successful"=>true}

Outgoing message don't have data field but when i change RealtimeAuth incoming function to this:

 def incoming(message, callback)
    puts "---- INCOMING ----"
    puts message.inspect
    if message['channel'] == '/meta/subscribe'
      puts "SUBSCRIBE CHANNEL"
      # my authentication logic
    end
    puts "OTHER CHANNEL"
    callback.call(message)
  end

Everything works:

---- INCOMING ----
{"channel"=>"/realtime_events/2", "data"=>{:type=>"chat_invitation", :thread_id=>4, :sender_id=>13, :sender_name=>"johnny"}, "clientId"=>"b07yf7b1nbuorqqeoj5jh0efow2uf6f", "id"=>"2"}
OTHER CHANNEL

---- OUTGOING ----
{"channel"=>"/realtime_events/2", "data"=>{:type=>"chat_invitation", :thread_id=>4, :sender_id=>13, :sender_name=>"johnny"}, "id"=>"2"}

Can someone explain why this don't work as expected? Thanks for help.

toomus commented 9 years ago

OK, so callback.call(message) must be in the end of incoming() and outgoing() functions, and can't be in any conditional instruction like 'if', and must appear only once in all function? To stop message from being sent, because of eg. authentication fail, we have to set message['error'] field in incoming() function. Then outgoing() function, when detect 'error' in message, stops processing that message and send another message with information, that something went wrong. Good explanation?