2011-05-17 15 views
6

मैं रुबी में रनटाइम पर जेनरेट किया गया डेटा अपलोड करना चाहता हूं, कुछ ब्लॉक से अपलोड को खिलाने जैसा कुछ।रूबी में मेमोरी से HTTP स्ट्रीम स्ट्रीम डेटा कैसे कर सकता हूं?

सभी उदाहरणों को मैंने केवल यह दिखाया कि अनुरोध से पहले डिस्क पर होने वाली फ़ाइल को स्ट्रीम करना है, लेकिन मैं फ़ाइल को बफर नहीं करना चाहता हूं।

अपना सॉकेट कनेक्शन रोल करने के अलावा सबसे अच्छा समाधान क्या है?

यह एक स्यूडोकोड उदाहरण:

post_stream('127.0.0.1', '/stream/') do |body| 
    generate_xml do |segment| 
    body << segment 
    end 
end 

उत्तर

1

वहाँ एक Net :: HTTPGenericRequest # body_stream = (obj.should respond_to (?: पढ़ें)) है

आप इसे और अधिक या कम इस तरह का उपयोग करें:


class Producer 
    def initialize 
    @mutex = Mutex.new 
    @body = '' 
    end 

    def read(size) 
    @mutex.synchronize { 
     @body.slice!(0,size) 
    } 
    end 

    def produce(str) 
    @mutex.synchronize { 
     @body << str 
    } 
    end 
end 

# Create a producer thread 

req = Net::HTTP::Post.new(url.path) 
req.body_stream = producer 
res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) } 
+0

दूसरे विचार पर, शायद म्यूटेक्स सबसे अच्छा दृष्टिकोण नहीं है, क्योंकि आप ब्लॉक करना चाहते हैं जबकि ईओएफ तक नहीं पहुंचा जा सकता है। लेकिन धागे प्रोग्रामिंग एक अलग कहानी है। Http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html – Roman

+0

ठीक है, यह सुनकर खुशी हुई कि यह आपके लिए काम करता है! कृपया इस उत्तर को "स्वीकृत" के रूप में चिह्नित करें, फिर :) – Roman

2

कोड जो काम करता है।

require 'thread' 
    require 'net/http' 
    require 'base64' 
    require 'openssl' 

    class Producer 
     def initialize 
     @mutex = Mutex.new 
     @body = '' 
     @eof = false 
     end 

     def eof!() 
     @eof = true 
     end 

     def eof?() 
     @eof 
     end 

     def read(size) 
     @mutex.synchronize { 
      @body.slice!(0,size) 
     } 
     end 

     def produce(str) 
     if @body.empty? && @eof 
      nil 
     else 
      @mutex.synchronize { @body.slice!(0,size) } 
     end 
     end 
    end 

    data = "--60079\r\nContent-Disposition: form-data; name=\"file\"; filename=\"test.file\"\r\nContent-Type: application/x-ruby\r\n\r\nthis is just a test\r\n--60079--\r\n" 

    req = Net::HTTP::Post.new('/') 
    producer = Producer.new 
    req.body_stream = producer 
    req.content_length = data.length 
    req.content_type = "multipart/form-data; boundary=60079" 

    t1 = Thread.new do 
     producer.produce(data) 
     producer.eof! 
    end 

    res = Net::HTTP.new('127.0.0.1', 9000).start {|http| http.request(req) } 
    puts res 
+0

एक उदाहरण जोड़ा गया :) – Roman

+0

धन्यवाद। मैंने कुछ कोड जोड़ा है जो लगभग काम करता है लेकिन नेट के साथ लाइन: कोड के अंत में HTTP कभी वापस नहीं आती है। कोई सुझाव? – Sam

+0

जब आप यह तय करते हैं कि भेजने के लिए कुछ भी नहीं बचा है तो आपको शून्य वापस करना होगा। उत्पादक/खपत व्यवसाय तर्क आमतौर पर इस तरह से चला जाता है: "क्या ईओएफ पहुंचा है? यदि ऐसा है तो वापसी करें, और यदि नहीं, तो क्या कुछ भेजने के लिए है? - डेटा भेजने के लिए अन्यथा ब्लॉक करें, भेजें। स्थिति की स्थिति जांचें - http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html#UF – Roman

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