wbsurfver-/E1597aS9LQAvxtiuMwx3w@public.gmane.org
2012-Mar-29 18:06 UTC
Not sure about event machine workings
I found this example of using faye for a chatroom type app as I am trying to get a feel for push servers: http://net.tutsplus.com/tutorials/ruby/how-to-use-faye-as-a-real-time-push-server-in-rails/ I got some of that to work, although multiuser from the same browser doesn''t exactly make sense. I then tried to look into a server side client. I am using a windows laptop for everything. I have the following code below which publishes a message to the chatroom fine, but it never really exits. The last statement "puts ''end''" is never reached. If I put EM.stop or an exit statement inside the event machine block, then the messages don''t make it to the chat room. The other thin I noticed is if I have a loop that puts say 5 messages to the chat room, but sleeps for several seconds between each. They don''t show up until they have all been published. It''s like it needs to reach the bottom of the block, but once there it never exits the block. require ''eventmachine'' require ''faye'' client = Faye::Client.new(''http://localhost:9292/faye'') EM.run { client.subscribe(''/messages/public'') do |message| puts message.inspect end client.publish(''/messages/public'', ''username'' => ''Joe'', ''msg'' => "hey there again") } puts ''end'' -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
When you enter a eventmachine block it never return control to your app. You have to turn it on but dont stay inside the evented block. Use this method before initializing comunication to faye def self.ensure_reactor_running Thread.new { EM.run } unless EM.reactor_running? sleep 0.1 until EM.reactor_running? end this will start eventmachine in a thread that is not the one your rails app is running if not already running. Just call ensure_reactor_running before subscribing -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
wbsurfver-/E1597aS9LQAvxtiuMwx3w@public.gmane.org
2012-Mar-29 23:28 UTC
Re: Not sure about event machine workings
Your post has been very helpful, I tried something like what you posted, but it didn''t quite make sense to me. If you look at what I have currently below, I have to have this sleep(30) at the bottom which is not optimal. a join on the thread doesn''t work. I also tried run_block() instead of run() with no luck. I guess if I do everything inside of a EM that doesn''t take too long, it wouldn''t matter, but I am trying to get an idea of how this sort of thing should work ######################### require ''eventmachine'' require ''faye'' client = Faye::Client.new(''http://localhost:9292/faye'') thr = nil if !EM.reactor_running? thr = Thread.new do EM.run do puts ''in ev machine'' client.subscribe(''/messages/public'') do |message| puts message.inspect end puts ''1'' client.publish(''/messages/public'', ''username'' => ''Joe'', ''msg'' => "hey there againzoggle") sleep 10 puts ''2'' client.publish(''/messages/public'', ''username'' => ''Joe'', ''msg'' => "hey there again") puts ''end of ev machine block'' end end end puts ''wait for running'' sleep 0.1 until EM.reactor_running? sleep 30 puts ''end of client'' -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
On Thu, Mar 29, 2012 at 7:28 PM, wbsurfver-/E1597aS9LQAvxtiuMwx3w@public.gmane.org <wbsurfver-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>wrote:> Your post has been very helpful, I tried something like what you > posted, but it didn''t > quite make sense to me. > > If you look at what I have currently below, I have to have this > sleep(30) at the bottom which is not optimal. > a join on the thread doesn''t work. > > I also tried run_block() instead of run() with no luck. > > I guess if I do everything inside of a EM that doesn''t take too long, > it wouldn''t matter, but I am trying to get an idea of > how this sort of thing should work > > ######################### > > > require ''eventmachine'' > > require ''faye'' > > > > client = Faye::Client.new(''http://localhost:9292/faye'') > > thr = nil > > if !EM.reactor_running? > thr = Thread.new do > EM.run do > > puts ''in ev machine'' > client.subscribe(''/messages/public'') do |message| > puts message.inspect > end > > puts ''1'' > > client.publish(''/messages/public'', ''username'' => ''Joe'', > ''msg'' => "hey there againzoggle") > sleep 10 > puts ''2'' > > client.publish(''/messages/public'', ''username'' => ''Joe'', > ''msg'' => "hey there again") > puts ''end of ev machine block'' > end > end > > end > > puts ''wait for running'' > sleep 0.1 until EM.reactor_running? > > sleep 30 > > puts ''end of client''Ok, Rails is a single threaded application, once you start event machine inside the application flow, control is lost until a event triggers a return somehow. Do not put your code inside the EM block. This is how i do it class CommBridge def self.set_connection ensure_reactor_running @@client ||= self.set @@client end private def self.set client = Faye::Client.new("http://localhost:9292/faye", {timeout: 20}) client.add_extension(ClientAuth.new) return client end def self.ensure_reactor_running Thread.new { EM.run } unless EM.reactor_running? sleep 0.1 until EM.reactor_running? end end class ClientAuth def outgoing(message, callback) if message[''channel''] !~ %r{^/meta/} message[''ext''] ||= {} message[''ext''][''authToken''] = "#{FAYE_TOKEN}" end callback.call(message) end end This calls takes care of creating a client fot he rails server. Then anywhere in your app client = CommBridge.set_connection client.publish("/user/#{channel}",msg.to_json) -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.