2010-01-24 19 views
8
require 'net/http' 

urls = [ 
    {'link' => 'http://www.google.com/'}, 
    {'link' => 'http://www.yandex.ru/'}, 
    {'link' => 'http://www.baidu.com/'} 
] 

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

print urls

यह कोड तुल्यकालिक शैली में काम करता है। पहला अनुरोध, दूसरा, तीसरा। मैं सभी अनुरोधों को असीमित रूप से भेजना चाहता हूं और उन सभी के बाद urls प्रिंट करना चाहता हूं।असीमित रूप से एकाधिक HTTP अनुरोध बनाना

ऐसा करने का सबसे अच्छा तरीका क्या है? क्या फाइबर इसके लिए उपयुक्त है?

उत्तर

1

यह सी लाइब्रेरी cURL के साथ किया जा सकता है। उस लाइब्रेरी के लिए ruby binding मौजूद है, लेकिन यह बॉक्स के बाहर इस कार्यक्षमता का समर्थन नहीं करता है। हालांकि, ऐसा लगता है कि a patch इसे जोड़ना/ठीक करना (उदाहरण कोड पृष्ठ पर उपलब्ध है)। मुझे पता है कि यह बहुत अच्छा नहीं लगता है, लेकिन अगर कोई बेहतर सुझाव नहीं है तो यह कोशिश करने लायक हो सकता है।

0

आप एक अलग धागा Net :: HTTP.get में से हर एक पर अमल हो सकता था। और बस सभी धागे खत्म करने के लिए प्रतीक्षा करें।

बीटीडब्ल्यू प्रिंटिंग यूआरएल लिंक और सामग्री दोनों प्रिंट करेंगे।

12

यहां धागे का उपयोग करके एक उदाहरण दिया गया है।

require 'net/http' 

urls = [ 
    {'link' => 'http://www.google.com/'}, 
    {'link' => 'http://www.yandex.ru/'}, 
    {'link' => 'http://www.baidu.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 

sleep 
+0

लगता है जैसे कि यह काम करता है। लेकिन 15 सेकंड के बाद सर्वर प्रतिक्रिया नहीं देता है तो थ्रेड को कैसे मारना है? – NVI

+1

आप 'टाइमआउट.टाइटू (20) करते हैं .... एंड' का उपयोग कर सकते हैं। इससे कोई त्रुटि उत्पन्न होती है, हालांकि, आपको अपने प्रोग्राम के प्रवाह के साथ कुछ करने की आवश्यकता होगी, और टैगिंग का एक तरीका है कि यह जांचने के अलावा कि कोई सामग्री 'कुंजी' मौजूद है या नहीं, यह अनुरोध समाप्त हो गया है। –

+0

रूबी का नेट :: HTTP थ्रेडसेफ है? – Daniel777

11

मैं सिर्फ यह देखा था, एक साल और थोड़ी देर बाद, लेकिन उम्मीद है कि नहीं भी ...

Typhoeus कुछ गूगलर के लिए देर से अब तक इसके लिए सबसे अच्छा समाधान। यह वास्तव में सुरुचिपूर्ण फैशन में libcurl लपेटता है। आप max_concurrency को लगभग 200 तक चॉकिंग के बिना सेट कर सकते हैं।

टाइमआउट के संबंध में, यदि आप टाइफियस को :timeout ध्वज पास करते हैं, तो यह केवल प्रतिक्रिया के रूप में टाइमआउट पंजीकृत करेगा ... और फिर आप चाहें तो पुनः प्रयास करने के लिए अनुरोध को फिर से अन्य हाइड्रा में भी डाल सकते हैं।

यहां आपका प्रोग्राम टायफियस के साथ पुनः लिखा गया है। उम्मीद है कि यह किसी भी व्यक्ति को बाद में इस पृष्ठ पर आने में मदद करता है!

require 'typhoeus' 

urls = [ 
    'http://www.google.com/', 
    'http://www.yandex.ru/', 
    'http://www.baidu.com/' 
] 

hydra = Typhoeus::Hydra.new 

successes = 0 

urls.each do |url| 
    request = Typhoeus::Request.new(url, timeout: 15000) 
    request.on_complete do |response| 
     if response.success? 
      puts "Successfully requested " + url 
      successes += 1 
     else 
      puts "Failed to get " + url 
     end 
    end 
    hydra.queue(request) 
end 

hydra.run 

puts "Fetched all urls!" if successes == urls.length 
0

work_queue मणि अपने आवेदन में अतुल्यकालिक रूप से और समवर्ती कार्य करने के लिए सबसे आसान तरीका है। 1) में सभी धागा संदर्भ पर नज़र रखता है: लेकिन कुछ महत्वपूर्ण अंतर के साथ -

wq = WorkQueue.new 2 # Limit the maximum number of simultaneous worker threads 

urls.each do |url| 
    wq.enqueue_b do 
    response = Net::HTTP.get_response(url) 
    # use the response 
    end 
end 

wq.join # All requests are complete after this 
1

मैं इस विषय है जो एक जवाब है कि कुछ हद तक एक अगस्त तक इसी तरह की है तैनात शामिल के बारे में बारे में गहराई से ब्लॉग पोस्ट में लिखा है "धागा" सरणी। 2) कार्यक्रम के अंत में धागे को बांधने के लिए "शामिल" विधि का उपयोग करता है।

require 'net/http' 

# create an array of sites we wish to visit concurrently. 
urls = ['link1','link2','link3'] 
# Create an array to keep track of threads. 
threads = [] 

urls.each do |u| 
    # spawn a new thread for each url 
    threads << Thread.new do 
    Net::HTTP.get(URI.parse(u)) 
    # DO SOMETHING WITH URL CONTENTS HERE 
    # ... 
    puts "Request Complete: #{u}\n" 
    end 
end 

# wait for threads to finish before ending program. 
threads.each { |t| t.join } 

puts "All Done!" 

पूर्ण ट्यूटोरियल (और कुछ प्रदर्शन जानकारी) यहाँ उपलब्ध है: https://zachalam.com/performing-multiple-http-requests-asynchronously-in-ruby/

संबंधित मुद्दे