[RUBY-ON-RAILS] 레일 3 루비 : 클라이언트에 레일을 통해 스트리밍 데이터
RUBY-ON-RAILS레일 3 루비 : 클라이언트에 레일을 통해 스트리밍 데이터
나는 루비 레일에 응용 프로그램 일하고 그 랙 스페이스의 cloudfiles와 통신 (아마존 S3와 유사하지만 일부 기능을 결여).
때문에 당 오브젝트 액세스 권한의 가용성 및 쿼리 문자열 인증의 부족으로, 사용자가 다운로드하는 응용 프로그램을 통해 중재해야합니다.
레일 2.3에서는 다음과 같이 동적 응답을 구축 할 수 있습니다 같다 :
# Streams about 180 MB of generated data to the browser.
render :text => proc { |response, output|
10_000_000.times do |i|
output.write("This is line #{i}\n")
end
}
(행 http://api.rubyonrails.org/classes/ActionController/Base.html#M000464)
대신 10_000_000.times의 ... 나는 거기에 내 cloudfiles 스트림 생성 코드를 덤프 수 있습니다.
문제는 내가 레일 3에서이 기술을 사용하려고 할 때 내가 얻을 출력이다.
#<Proc:0x000000010989a6e8@/Users/jderiksen/lt/lt-uber/site/app/controllers/prospect_uploads_controller.rb:75>
같은 외모는 어쩌면 시저 객체의 호출 메서드가 호출되지 않는? 어떤 다른 아이디어?
해결법
-
==============================
1.이 레일에서 사용할 수없는 것 같습니다 3
이 레일에서 사용할 수없는 것 같습니다 3
https://rails.lighthouseapp.com/projects/8994/tickets/2546-render-text-proc
이것은 내 컨트롤러에서 나를 위해 일에 출연 :
self.response_body = proc{ |response, output| output.write "Hello world" }
-
==============================
2.응답이 #each에 개체를 response_body에 할당 :
응답이 #each에 개체를 response_body에 할당 :
class Streamer def each 10_000_000.times do |i| yield "This is line #{i}\n" end end end self.response_body = Streamer.new
당신이 1.9.x 또는 백 포트 보석을 사용하는 경우, 당신은 더 많은 콤팩트 Enumerator.new를 사용하여이 쓸 수 있습니다 :
self.response_body = Enumerator.new do |y| 10_000_000.times do |i| y << "This is line #{i}\n" end end
데이터가 플러시 될 경우 랙 핸들러 기반 서버에 의존 할 때 사용되는 것을 유의해야한다. 나는 잡종은, 예를 들어, 데이터를 스트리밍 것을 확인했지만, 다른 사용자에 WEBrick은, 예를 들어, 버퍼를 응답이 닫힐 때까지보고있다. 플러시에 대한 응답을 강제 할 수있는 방법은 없습니다.
레일 3.0.x 버전에서 몇 가지 추가 망 가지고있다 :
이 두 문제는 HTTP 스트리밍 윤곽 기능입니다 레일 3.1에 고정되어 있습니다.
참고 다른 일반적인 제안, self.response_body = PROC {| 응답, 출력 | ...}, 레일 3.0.x 버전에서 작업을 수행하지만, 사용되지 않습니다 (더 이상 실제로 데이터를 스트리밍하지 않습니다) 3.1. 응답 모든 레일 3 버전에서 작품을 #each하는 것을 객체를 할당.
-
==============================
3.모든 게시물에 대한 감사 위, 여기에 완벽하게 코드를 작동하는 것은 큰 CSV를 스트리밍합니다. 이 코드 :
모든 게시물에 대한 감사 위, 여기에 완벽하게 코드를 작동하는 것은 큰 CSV를 스트리밍합니다. 이 코드 :
컨트롤러 방법 :
def csv_export respond_to do |format| format.csv { @filename = "responses-#{Date.today.to_s(:db)}.csv" self.response.headers["Content-Type"] ||= 'text/csv' self.response.headers["Content-Disposition"] = "attachment; filename=#{@filename}" self.response.headers['Last-Modified'] = Time.now.ctime.to_s self.response_body = Enumerator.new do |y| i = 0 Model.find_each do |m| if i == 0 y << Model.csv_header.to_csv end y << sr.csv_array.to_csv i = i+1 GC.start if i%500==0 end end } end end
설정 / unicorn.rb
# Set to 3 instead of 4 as per http://michaelvanrooijen.com/articles/2011/06/01-more-concurrency-on-a-single-heroku-dyno-with-the-new-celadon-cedar-stack/ worker_processes 3 # Change timeout to 120s to allow downloading of large streamed CSVs on slow networks timeout 120 #Enable streaming port = ENV["PORT"].to_i listen port, :tcp_nopush => false
Model.rb
def self.csv_header ["ID", "Route", "username"] end def csv_array [id, route, username] end
-
==============================
4.경우에 당신은 응답이 닫힐 때까지 #each 방법에 응답하고 그것의 버퍼링이, 액션 컨트롤러에서 보는 것이 객체를 response_body에 할당된다 :
경우에 당신은 응답이 닫힐 때까지 #each 방법에 응답하고 그것의 버퍼링이, 액션 컨트롤러에서 보는 것이 객체를 response_body에 할당된다 :
self.response.headers [ '마지막으로 수정'] = Time.now.to_s
-
==============================
5.그냥 기록을 위해,> = 3.1 개체를 할당하여 데이터를 스트리밍 할 수있는 쉬운 방법이 레일 컨트롤러의 응답 #each 방법에 대한 응답이.
그냥 기록을 위해,> = 3.1 개체를 할당하여 데이터를 스트리밍 할 수있는 쉬운 방법이 레일 컨트롤러의 응답 #each 방법에 대한 응답이.
모든 것이 여기에 설명 : http://blog.sparqcode.com/2012/02/04/streaming-data-with-rails-3-1-or-3-2/
-
==============================
6.예, response_body는 잠시 동안이 일의 레일 3 방법은 다음과 같습니다 https://rails.lighthouseapp.com/projects/8994/tickets/4554-render-text-proc-regression
예, response_body는 잠시 동안이 일의 레일 3 방법은 다음과 같습니다 https://rails.lighthouseapp.com/projects/8994/tickets/4554-render-text-proc-regression
-
==============================
7.이뿐만 아니라 내 문제를 해결 - 나는 GzipReader를 사용하여 한 번에 그들에게 선을 읽을 수 있도록 나는, 압축을 푼 CSV로 사용자에게 보내려면, CSV 파일을 gzip으로 압축했다.
이뿐만 아니라 내 문제를 해결 - 나는 GzipReader를 사용하여 한 번에 그들에게 선을 읽을 수 있도록 나는, 압축을 푼 CSV로 사용자에게 보내려면, CSV 파일을 gzip으로 압축했다.
당신은 다운로드로 큰 파일을 제공하려는 경우이 라인도 도움이됩니다 :
self.response.headers [ "의 Content-Type"] = "응용 프로그램 / octet-stream을" self.response.headers [ "콘텐츠 - 처리"= "첨부 파일, 파일 이름 = #} {파일명"
-
==============================
8.또한, 당신은 당신의 자신에 의해 '콘텐츠 길이'헤더를 설정해야합니다.
또한, 당신은 당신의 자신에 의해 '콘텐츠 길이'헤더를 설정해야합니다.
그렇지 않은 경우, 랙의 길이를 결정합니다 (메모리에 본문 데이터를 버퍼링) 기다려야 할 것이다. 그리고 위에서 설명한 방법을 사용하여 당신의 노력을 파괴 할 것이다.
내 경우, 나는 길이를 결정할 수있다. 경우에 당신은, 당신은 '콘텐츠 길이'헤더없이 몸을 보내기 시작 랙을 만들 필요가 없습니다. '실행'하기 전에 '필요'후 config.ru에 "사용 랙 : 청크 분할"을 추가하려고합니다. (감사 arkadiy)
-
==============================
9.난 그냥 성공 대신에 WEBrick의 잡종을 사용하는 데 필요한 불구하고 self.response_body = PROC의 접근 방식은 나를 위해 일한 말하고 싶었다, 등대 티켓에 댓글을 달았습니다.
난 그냥 성공 대신에 WEBrick의 잡종을 사용하는 데 필요한 불구하고 self.response_body = PROC의 접근 방식은 나를 위해 일한 말하고 싶었다, 등대 티켓에 댓글을 달았습니다.
남자 이름
-
==============================
10.나를 위해 일한 Exequiel의 제안과 함께 요한의 솔루션을 적용.
나를 위해 일한 Exequiel의 제안과 함께 요한의 솔루션을 적용.
문
self.response.headers['Last-Modified'] = Time.now.to_s
마크 랙에 캐시 할 수없는 응답.
추가 조사 후, 나는 하나가이 사용할 수 생각 :
headers['Cache-Control'] = 'no-cache'
이것은 나에게, 단지 약간 더 직관적이다. 그것은 내 코드를 읽을 수 있습니다 다른 any1에 메시지를 전달한다. 또한, 경우에 랙의 미래 버전이 마지막으로 수정 검사 중지, 많은 코드가 깨질 수 있으며, 그 이유를 알아 내기 위해 사람들을위한 잠시 동안 할 수있다.
from https://stackoverflow.com/questions/3507594/ruby-on-rails-3-streaming-data-through-rails-to-client by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 하나 개의 배열이 다른 배열의 모든 요소가 포함되어 있는지 확인하는 방법 (0) | 2020.02.07 |
---|---|
[RUBY-ON-RAILS] 어떻게 명시 적으로 레일에서 모델의 테이블 이름 매핑을 지정합니까? (0) | 2020.02.07 |
[RUBY-ON-RAILS] 레일에서보기 당 자바 스크립트 파일 (0) | 2020.02.07 |
[RUBY-ON-RAILS] 가 현재 설치되어 있지 있다고 말해 계속 레일 (0) | 2020.02.07 |
[RUBY-ON-RAILS] 레일을 직렬화를 사용하여 데이터베이스에 해시를 저장합니다 (0) | 2020.02.07 |