потоковое несколько тел с помощью асинхронного синатра - PullRequest
3 голосов
/ 11 февраля 2011

Я хотел бы начать длинный запрос опроса от javascript, что нормально, и я ожидаю, что моя программа ruby ​​будет передавать несколько разделов тела в javascript.Почему не работает следующий (псевдо) код?

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

Может быть, я неправильно понял, что должны делать длинные опросы и асинхронность, но я ожидаю, что я получу несколько тел, отправленных обратно клиенту?Мне нужно использовать eventmachine или что-то?

спасибо

Ответы [ 2 ]

6 голосов
/ 01 июля 2011
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

Смотри также: http://confreaks.net/videos/564-scotlandruby2011-real-time-rack

1 голос
/ 11 февраля 2011

В примере ниже показано, что вам нужно событие EventMachine для запуска отправки нескольких тел. Также см. Этот предыдущий ответ .

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
...