web-dev-qa-db-ja.com

rubyの非同期httpリクエスト

 require 'net/http'

urls = [
  {'link' => 'http://www.google.com/'},
  {'link' => 'http://www.facebook.com/'},
 {'link' => 'http://www.yahoo.com/'}
]

urls.each do |u|
  u['content'] = Net::HTTP.get( URI.parse(u['link']) )
end

print urls

これは手続き型コードとして機能します。サーバーにアクセスしたいだけで、注文に関する問題はありません。 Rubyでそれを行うにはどうすればよいですか。 1つのオプションは、スレッドを使用することです。

スレッドを使用した例を次に示します。

require 'net/http'

urls = [
  {'link' => 'http://www.google.com/'},
  {'link' => 'http://www.facebook.com/'},
  {'link' => 'http://www.yahoo.com/'}
]

urls.each do |u|
  Thread.new do
    u['content'] = Net::HTTP.get( URI.parse(u['link']) )
    puts "Successfully requested #{u['link']}"

    if urls.all? {|u| u.has_key?("content") }
      puts "Fetched all urls!"
      exit
    end
  end
end

より良い解決策.. ??

PS:-私はミックスパネルをヒットしたいので、私はただhttpコールを行い、応答を待たない理由です。

31
Mohit Jain

軽量非同期処理は、スレッド(あなたが言ったように)または ファイバー の仕事です。

それ以外の場合は、非常に強力なツールである EventMachine を検討する必要があります。

編集:上記のEvent MachineのURLは無効です。これがGitHubアカウント https://github.com/eventmachine/eventmachine です。それは良い出発点として役立ちます。

14
apneadiving

これが 素晴らしい記事 のトピックです。

一般的に、これにスレッドを使用する代わりに実行可能な代替方法は Fiber を使用するか、または em-http-request を使用できます。後者の例では、特定の目的のコールバック処理を省略できます。

12
emboss

非同期形式での単純なhttp要求の場合、おそらく nirest がそれを達成するのに最適です。

Asncリクエストは次のようにシンプルです:

response = Unirest.post "http://httpbin.org/post", 
                    headers:{ "Accept" => "application/json" }, 
                    parameters:{ :age => 23, :foo => "bar" } {|response|
response.code # Status code
response.headers # Response headers
response.body # Parsed body
response.raw_body # Unparsed body
}
2
Sumit Malik