일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 이더리움
- CORDA
- Actor
- 엔터프라이즈 블록체인
- 스칼라 강좌
- Golang
- Play2 로 웹 개발
- 파이썬
- 파이썬 동시성
- 스칼라
- play2 강좌
- 스위프트
- 그라파나
- Hyperledger fabric gossip protocol
- hyperledger fabric
- 플레이프레임워크
- Akka
- 파이썬 머신러닝
- play 강좌
- 하이퍼레저 패브릭
- akka 강좌
- 주키퍼
- 파이썬 데이터분석
- 파이썬 강좌
- 블록체인
- 하이브리드앱
- Adapter 패턴
- 안드로이드 웹뷰
- 스칼라 동시성
- Play2
- Today
- Total
HAMA 블로그
[Play2] Streaming HTTP responses (File, Chunked) (번역) 본문
[Play2] Streaming HTTP responses (File, Chunked) (번역)
[하마] 이승현 (wowlsh93@gmail.com) 2017. 3. 19. 20:04Streaming HTTP responses
Standard responses and Content-Length header
HTTP 1.1부터 여러 HTTP 요청과 응답을 제공하기 위한 단일 연결을 유지하기 위해, 서버는 적절한 Content-Length HTTP 헤더를 응답과 함께 보내야합니다.
기본적으로 아래와 같지요.
public Result index() {
return ok("Hello World");
}
특별히 Content-Length 헤더를 지정하지 않았습니다. 물론, 보내는 콘텐츠가 잘 알려져 있기 때문에 Play는 콘텐츠 크기를 계산하고 적절한 헤더를 생성 할 수 있습니다.
참고 : 텍스트 기반 콘텐츠의 경우 Content-Length header가 문자를 바이트로 변환하는 데 사용되는 인코딩에 따라 계산되어야 하므로 모양이 단순하지 않습니다.
Content-Length 헤더를 올바르게 계산하려면 Play가 전체 응답 데이터를 소비하고 해당 내용을 메모리에 로드해야합니다.
Serving files
간단한 콘텐츠를 위해 전체 콘텐츠를 메모리에 로드하는 것 말고 대용량 데이터는 어떻게 할까요? 우리가 큰 파일을 웹 클라이언트로 되돌려 보내려한다고 가정 해 봅시다.
Play는 로컬 파일을 제공하는 일반적인 작업에 사용하기 쉬운 도우미를 제공합니다.
public Result index() {
return ok(new java.io.File("/tmp/fileToServe.pdf"));
}
또한 이 헬퍼는 파일 이름에서 Content-Type 헤더를 계산합니다. 그리고 Content-Disposition 헤더를 추가하여 웹 브라우저가 이 응답을 처리하는 방법을 지정합니다. 기본값은 Content-Disposition : attachment를 사용하여 , 이 파일을 다운로드 하도록 웹 브라우저에 요청하는 것이죠. filename = fileToServe.pdf.
Chunked responses
지금까지는 스트리밍 하기 전에 콘텐츠 길이를 계산할 수 있기 때문에 스트리밍 파일 콘텐츠와 잘 작동합니다. 그러나 콘텐츠 크기가 없는 동적으로 계산된 콘텐츠는 어떻게 할까요?
이러한 종류의 응답을 위해서는 청크 분할 전송 인코딩을 사용해야합니다.
참고: 청크 분할 전송 인코딩은 웹 서버가 일련의 청크로 콘텐츠를 제공하는 HTTP 1.1 버전의 데이터 전송 메커니즘입니다. 이것은 프로토콜이 필요로 하는 Content-Length 헤더 대신 Transfer-Encoding HTTP 응답 헤더를 사용합니다. Content-Length 헤더가 사용되지 않기 때문에 서버는 클라이언트 (일반적으로 웹 브라우저)에 대한 응답 전송을 시작하기 전에 내용의 길이를 알 필요가 없습니다. 웹 서버는 동적으로 생성 된 컨텐트를 사용하여 응답을 전송하기 전에 해당 컨텐트의 전체 크기를 알 수 있습니다.
각 청크의 크기는 청크 자체 바로 전에 보내 지므로 클라이언트는 청크에 대한 데이터 수신이 완료된 시점을 알 수 있습니다. 데이터 전송은 길이가 0 인 최종 청크에 의해 종료됩니다.
장점은 우리가 데이터를 실시간으로 제공 할 수 있다는 것입니다. 즉, 우리는 준비된 데이터를 가능한 빨리 데이터 덩어리로 보냅니다. 단점은 웹 브라우저가 콘텐츠 크기를 알지 못하기 때문에 적절한 다운로드 진행률 표시 줄을 표시 할 수 없다는 것입니다.
일부 데이터를 계산하는 동적인 InputStream을 제공하는 어딘가에 서비스가 있다고 가정 해 보겠습니다. 우리는 청크 응답을 사용하여 Play에 이 콘텐츠를 직접 스트리밍 하도록 요청할 수 있습니다.
public Result index() {
InputStream is = getDynamicStreamSomewhere();
return ok(is);
}
자체 청크 응답 빌더를 설정할 수도 있습니다. (EvenSource 등)
public Result index() {
// Prepare a chunked text stream
Source<ByteString, ?> source = Source.<ByteString>actorRef(256, OverflowStrategy.dropNew())
.mapMaterializedValue(sourceActor -> {
sourceActor.tell(ByteString.fromString("kiki"), null);
sourceActor.tell(ByteString.fromString("foo"), null);
sourceActor.tell(ByteString.fromString("bar"), null);
sourceActor.tell(new Status.Success(NotUsed.getInstance()), null);
return null;
});
// Serves this stream with 200 OK
return ok().chunked(source);
}
Source.actorRef 메서드는 ActorRef에 구체화하는 Akka stream소스를 만듭니다. 그런 다음 액터로 메시지를 보내 스트림에 요소를 게시 할 수 있습니다. 다른 방법은 ActorPublisher를 확장하고 Stream.actorPublisher 메서드를 사용하여 ActorPublisher를 만드는 액터를 만드는 것입니다.
서버가 보낸 HTTP 응답을 검사 할 수 있습니다.
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
4
kiki
3
foo
3
bar
0
우리는 응답을 닫는 세 개의 청크와 하나의 마지막 빈 청크를 얻습니다.
'PlayFramework2' 카테고리의 다른 글
[Play2] Body parsers 이해하기 (0) | 2017.03.21 |
---|---|
평범한 사람들을 위한 Play2 Iteratees 의 이해 [번역] (0) | 2017.03.20 |
Angular2 , 웹팩을 Play 와 함께 사용하기 [번역] (0) | 2017.03.16 |
[Play2] Action 과 Action.async 의 차이점 (0) | 2017.02.26 |
[Play2] Iteratee & Enumerators 간단 정리 (0) | 2017.02.18 |