2011-02-11 4 views
3

javascriptからの長いポーリングリクエストを開始したいと思います。私はRuby Progが複数のボディセクションをJavascriptにストリームすることを期待しています。なぜ、次の(疑似)コードは機能しませんか?async sinatraを使用したスト​​リームの複数のボディ

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イベントを必要とする以下のexampleに表示されます

おかげ

+0

私も今、これに取り組んでいます。私が理解していることから、体は要求書いたストリームを閉じてそれを送ります。 'body 'asdf''を連続して2回呼び出すと、ページにはasdfだけが表示されます。代わりにwrite、またはresponse.writeを使用することを提案した1つのリードが見つかりました。それは私の接続がブラウザでまだ開いているのが分かるので、より良いようです。この問題は、行内の2つの 'write'呼び出しが期待どおりに動作しないことです。 –

+0

** BOUNTY INFO **:私は、A)このアプローチが実現できない理由を説明することができます(つまり、私が疑ういくつかのHTTP仕様のために)。 B)身体に書いてブラウザに表示するコードを入力し、2秒後に本体に書き込んで、この更新をブラウザに表示させる。 誰かがあなたの答えに触れて、報奨金を得ることを望む場合を除き、参照番号または作業コードを提供してください:) –

+0

これに遅れて返答して申し訳ありませんが、私はこの仕事をもう一度(1.5年後)選んでいました。したがって、ここでのユースケースは、たとえば、Webページを介してトリガされたFTP操作を行っていたとします。このウェブページでは、基本的にリアルタイムでアップロードされたバイトを取得したいと思っていました。コマンドラインに出力を示すnetftpを使った例がたくさんあります。しかし、あなたのコードはウェブページ経由でどのようにできるかを示していると思います。私はまた、Sinatraとは対照的にRamaze経由でそれをしたいと思っています。 – gurpal2000

答えて

6
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

+0

まだ話を進めていますが、ストリーミング。 **素早い対応のために**ありがとうございました(この話をすると、これまであなたがこれまであなたであったことはわかりませんでした)。 (StackOverflowが必要です)私は賞金を授与されるまでにさらに6時間待つ必要があります。 –

+0

ところで、この手順のドキュメントを書くのを手伝って、他の人がこのプロセスを理解するのに時間を費やす必要がないようにしたいと思います。私は道に沿っていくつかの有用な情報も学ぶと確信しています。 HTTPストリーミングのドキュメントをどこに置くべきか、それをどのプロジェクトに追加するかに関する推奨事項はありますか? –

+1

私はしません。それはRackで正式にサポートされていないので、async_sinatra、私の非同期ラックプロジェクト(ハックのほうが多い)、薄い、まあまあではないかもしれません...ラックへの非同期拡張のためのある種の仕様は素晴らしいでしょう他のサーバー用に実装することも容易です。 –

1

。この前のanswerも参照してください。

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 
+1

申し訳ありませんが、どのように複数の団体を送っていますか?これは遅れた非同期応答を送信するだけですか? – gurpal2000

+0

私が知ることから、これはn秒遅れた身体を送信します。おそらく、gurpalが1つのリクエストに対して複数のボディを送信したり、1つのボディを送信したり、新しいデータが入ったときに更新されるようなストリーミング方法で混乱させたりするような混乱があるかもしれません。 –

関連する問題