2012-04-24 2 views
2

play 1.2.4를 사용하여 renderBinary() 메소드를 사용하여 대규모 바이너리 파일 다운로드를 사용자에게 성공적으로 제공하고 있습니다.Play 프레임 워크에서 파일 다운로드가 완료되면 알림

사용자가 실제로 다운로드를 완료 할 때 힌트를 갖고 싶습니다. 일반적으로 말하지만, 이전에 해본 것처럼 다소 가능합니다. 내 웹 사이트의 이전 버전에서는 이진 파일 다운로드를 제공하는 간단한 서블릿을 작성했습니다. 서블릿이 파일의 내용을 쓰면, 알림이 전송됩니다. 그럼에도 불구하고 완벽하지는 않지만 확실히 유용합니다. 테스트에서 사용자가 파일을 다운로드하는 데 걸린 시간을 알려줍니다.

재생 소스를 살펴보면 play.mvc.results.RenderBinary 클래스에 내가 사용할 수있는 편리한 apply() 메소드가 있음을 알 수 있습니다. apply() 메서드가 파일 내용을 쓰는 것을 마친 후에 알림을 보낼 수 있도록 RenderBinary의 자체 버전을 작성했습니다.

내가 발견 한 문제는 response.out.write()가 분명히 보내는 바이트를 (Netty를 통해) 캐시한다는 것입니다. 따라서 몇 메가 바이트의 데이터를 작성하더라도 play.mvc.Http .Response.out.write()는 다운로더에 파일을 다운로드하는 데 몇 분이 걸리지 만 몇 초 만에 완료됩니다.

주식 Play 1.2.4 배포판을 사용하고 싶지만 맞춤 수업을 작성하는 데 신경 쓰지 않아도됩니다.

파일 다운로드가 끝날 때 사용자의 브라우저로 푸시 알림을받는 방법에 대한 아이디어가 있으십니까?

어떻게 든 비슷한 문제가 태클로이, 당신이 도움이 될 것 같다

답변

0

:

Detect when browser receives file download

난 당신이 EB는 수 renderBinary을 통해 그것을 할 수 있습니다 모르겠어요이나 컨트롤러의 @After 주석을 . 일부 브라우저 측에서 다운로드를 감지 한 다음 서버에 알림 (다운로드가 끝날 때까지 ping을 실행)하면 작동합니다. 사용 WebSocket을 (소켓을 통해 파일을 스트리밍하고 TEH 클라이언트가 대답 할 필요)하지만이 잔인한 될 수있다 : 당신이 ArchivedEventStream을 사용할 수 있습니다

+0

웹 소켓을 통해 파일을 업로드 할 수있는 중요한 해결 방법이 곧 제공 될 예정입니다 ... https://github.com/playframework/play1/pull/709 –

0

:

대안이있을 수 있습니다.

먼저 직렬화 ArcivedEventStream 클래스를 만들 .. 컨트롤러에 다음

public class Stream<String> extends ArchivedEventStream<String> implements Serializable{ 

    public Stream(int arg0) { 
     super(arg0); 
    } 

} 

... 당신의 HTML에

public static void downloadPage(){ 
    Stream<String> userStream = Cache.get(session.getId(),Stream.class); 
    if(userStream == null){ 
     userStream = new Stream<String>(5); 
     Cache.add(session.getId(), userStream); 
    } 
    render(); 
} 

public static void download(){ 
    await(10000);// to provide some latency. actually no needed 
    renderBinary(Play.getFile("yourfile!")); 
} 

public static void isDownloadFinished(){ 
    Stream<String> userStream = Cache.get(session.getId(),Stream.class); 
    List<IndexedEvent<String>> list = await(userStream.nextEvents(0)); 
    renderJSON(list.get(0).data); 

} 

@After(only="download") 
static void after(){ 
    Stream<String> userStream = Cache.get(session.getId(),Stream.class); 
    userStream.publish("ok"); 
} 

...

#{extends 'main.html' /} 

#{set title:'downloadPage' /} 
<a href="download" target="_blank">download</a> 

<script> 
$(document).ready(function(){ 
$.ajax('/application/isDownloadFinished',{success:function(data){ 
    if(data){ 
     console.log("downloadFinished");  
    } 

}}); 
}); 

</script> 

는 다운로드가 완료 , 원본 페이지가 알림을 검색합니다.

이 코드는 예제입니다. ArchivedEventStream의 API를 읽고 직접 구현할 수 있습니다.

+0

ArchivedEventStream 버퍼 오버런을 막기 위해 패킷을 삭제합니다 .... 웹 소켓 전용 EventStream을 고치려는 폴 요청은 여기에 있습니다 ... 오늘의 경우와 같이 ArchivedEventStream에서 패킷을 삭제하지 않기를 원한다면 누군가 말을해야합니다 ... https : //github.com/playframework/play1/pull/709 –