Reputation: 1082
I would like start a long poll request from javascript which is fine and i expect my ruby prog to stream multiple body sections to the javascript. Why doesn the following (pseudo)code work?
require 'rubygems'
require 'sinatra/async'
require 'eventmachine'
require 'thin'
require 'json'
class Test < Sinatra:Base
register Sinatra::Async
aget '/process' do
for c in 1..10
body {
{ :data => [ "this is part #{c}" ] }.to_json
end
end
end
run!
end
Maybe i misunderstood what long polling and async is supposed to do, but my expectation is that i get multiple bodies sent back to the client ? Do i need to use eventmachine or something?
thanks
Upvotes: 3
Views: 3512
Reputation: 25964
require 'rubygems'
require 'sinatra/async'
require 'thin'
require 'json'
class Test < Sinatra::Base
register Sinatra::Async
class JSONStream
include EventMachine::Deferrable
def stream(object)
@block.call object.to_json + "\n"
end
def each(&block)
@block = block
end
end
aget '/process' do
puts 'ok'
out = JSONStream.new
body out
EM.next_tick do
c = 0
timer = EM.add_periodic_timer(0.3) do
c += 1
out.stream :data => ["this is part #{c}"]
if c == 100
timer.cancel
out.succeed
end
end
end
end
run!
end
See also: http://confreaks.net/videos/564-scotlandruby2011-real-time-rack
Upvotes: 6
Reputation: 6260
It appears in the example below that you need an EventMachine event to trigger the sending of the multiple bodies. Also see this previous answer as well.
require 'sinatra/async'
class AsyncTest < Sinatra::Base
register Sinatra::Async
aget '/' do
body "hello async"
end
aget '/delay/:n' do |n|
EM.add_timer(n.to_i) { body { "delayed for #{n} seconds" } }
end
end
Upvotes: 1