2012-03-23 97 views
1

我正在嘗試使用HTTP分塊傳輸編碼接收流數據的小ruby腳本。所以我在客戶端使用紅寶石結束了。我可以找到很多有關紅寶石(和導軌)服務流的問題和信息,但沒有太多關於消費他們。也許是因爲它很簡單,應該只是作爲HTTP的低級特性工作。那麼有人可以給我一個小樣本腳本?Ruby分塊編碼客戶端

我嘗試了幾件事情。這一次使用開放URI:

require 'open-uri' 

streamURL = 'http://localhost/sample-stream.php' 

puts "Opening" 

open(streamURL) do |f| 
    puts "Opening steam " + streamURL + " (never gets here)" 
    p f.meta 
    p "Content-Type: " + f.content_type 
    p "last modified" + f.last_modified.to_s 

    no = 1 
    # print the first three lines 
    f.each do |line| 
     print "#{no}: #{line}" 
     no += 1 
     break if no > 4 
    end 
end 

...而這一次使用網HTTP:

require 'net/http' 
require 'uri' 

streamURL = 'http://localhost/sample-stream.php' 

url = URI.parse(streamURL) 
full_path = (url.query.empty?) ? url.path : "#{url.path}?#{url.query}" 

the_request = Net::HTTP::Get.new(full_path, {'Transfer-Encoding' => 'chunked', 'content-type' => 'text/plain'}) 
#(Side question: Does it even make sense to specify 'chunked' in the request?) 

puts "Opening stream " + streamURL 

the_response = Net::HTTP.start(url.host, url.port) { |http| 
    http.request(the_request) 
} 

puts the_response.body #never gets here 

在這兩種情況下,它從不輸出任何東西,我可以在Apache中我的PHP腳本看到的是忙碌噴涌越來越多的數據。我認爲很清楚這裏發生了什麼問題。在這兩種情況下,我認爲我的腳本在處理它之前都在等待整個響應(永遠不會發生)。

我應該指出,有可能是壞了我的PHP腳本(服務器),但我可以看到它吹了塊很好地到Firefox。

那麼是否有一種簡單的ruby方式來傳輸數據?或者我應該期望需要特殊的寶石/庫來做到這一點? (我碰到例如this library

回答

2

我認爲下面的代碼應該可以工作。

require 'net/http' 

streamURL = 'http://localhost/sample-stream.php' 

uri = URI.parse(streamURL) 

Net::HTTP.start(uri.host, uri.port) do |http| 
    request = Net::HTTP::Get.new uri.request_uri 

    http.request request do |response| 
    response.read_body do |chunk| 
     #We get the data here chunk-by-chunk 
     puts chunk 
    end 
    end 
end 

其實這不適合我的樣本stream.php工作,但我曾與類似這樣的腳本運氣的東西,在另一臺服務器指向。我的工作代碼更復雜,因爲它也需要驗證,但我已經在這裏簡化了一下。

在我測試的PHP腳本指點,這個代碼導致有些有用的錯誤消息:

`read_chunked': wrong chunk size line: (Net::HTTPBadResponse) 

...這清楚地表明我做錯了的事情PHP服務器端。不知道什麼是錯的,但那是另一個問題。

+0

附加說明:我遇到了這個奇怪的問題。它高興地消耗流三到四分鐘,然後開始注入\ n2000 \ n定期到流中。也許這就是我看到的塊大小,除了它們似乎不對應塊的開始或結束。當然,我不期望看到任何協議級別的東西。很顯然,這些2000行對於我正在嘗試解析的內容大打折扣。使用wget我沒有看到同樣的問題,所以一定是在紅寶石網的HTTP錯誤?想知道是否有人遇到同樣的問題。 – 2012-05-28 13:22:55

+0

作爲更新...我看到這是因爲腳本跟不上流。當我寫入memcache而不是數據庫時解決。我很驚訝,我沒有得到更有用的「緩衝區滿」例外。所以我想這是需要注意的。 – 2013-02-28 16:35:37

-1

調用'wget'系統命令的另一種方法。

wget_command = "wget " + streamURL + " --user=myusername --password=mypassword -qO-" 

puts "Opening stream: " + wget_command 
f = open("|" + wget_command) 
    while (line = f.gets) 
    puts "LINE:" + line 
    end #(loops forever) 
end 

這似乎比首先使用ruby的網絡http更可靠,而且它肯定是更緊湊的代碼。作爲額外的好處,我可以很容易地逐行獲取數據(我從塊閱讀方法中得到的其他東西)我不確定這些缺點是什麼。以這種方式管理標準輸出數據可能效率低下。此外,這段代碼不會在沒有wget命令的平臺上工作(windows)但是對我來說,這看起來好像比網絡http好一點...

但是它在三四分鐘後仍然出現問題。我想象這是因爲流速過快,某處的某個緩衝區被填滿,或者因爲這個特定的流會在幾分鐘後減慢(不要問我爲什麼,它只是),所以也許當它終於迎頭趕上時,就會出現錯誤。

+0

注意! [你在玩火](http://sakurity.com/blog/2015/02/28/openuri.html) – Ich 2015-06-16 09:21:14