3

私は Play 1.2.4 を使用して、renderBinary() メソッドを使用してユーザーに大きなバイナリ ファイルのダウンロードを提供することに成功しています。

ユーザーが実際にいつダウンロードを完了するかについてのヒントが欲しいです。一般的に言えば、以前に行ったことがあるので、これがある程度可能であることはわかっています。私の Web サイトの古いバージョンで、バイナリ ファイルのダウンロードを提供する単純なサーブレットを作成しました。そのサーブレットがファイルの内容の書き出しを完了すると、通知が送信されました。確かに完璧ではありませんが、それでも有用です。私のテストでは、ユーザーがファイルをダウンロードするのにかかった時間を示していました。

Play のソースを確認すると、play.mvc.results.RenderBinary クラスに便利な apply() メソッドが含まれていることがわかります。独自のバージョンの RenderBinary を作成したので、apply() メソッドがファイル コンテンツの書き込みを終了した後に通知を送信できます。

私が見つけた問題は、response.out.write() の呼び出しが (Netty 経由で) 送信バイトを明らかにキャッシュすることです。ダウンローダーがファイルをダウンロードするのに数分かかりますが、.write() は数秒で完了します。

カスタム クラスを作成することは問題ありませんが、ストックの Play 1.2.4 ディストリビューションを使用することを好みます。

ファイルのダウンロードの終了がユーザーのブラウザにプッシュされたときに通知を受け取る方法についてのアイデアはありますか?

4

2 に答える 2

0

それはどういうわけか同様の問題に取り組むので、これはあなたを助けるかもしれないようです:

ブラウザがファイルのダウンロードを受信したことを検出する

コントローラrenderBinaryの注釈を介して、または注釈を介してそれを実行できるかどうかはわかりません。@Afterブラウザ側でのダウンロードの検出と、サーバーへの通知(ダウンロードの終了をpingする)が機能します。

別の方法があるかもしれません:WebSocketを使用する(ソケットを介してファイルをストリーミングし、クライアントに応答させる)が、これにはやり過ぎかもしれません:)

于 2012-04-25T10:06:29.543 に答える
0

ArchivedEventStreamを使用できます。

まず、シリアライズ可能な ArcivedEventStream クラスを作成します。

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

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

}

次に、コントローラーで...

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");
}

あなたのhtmlで...

#{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 を読み取って、独自の実装を作成できます。

于 2013-02-09T09:30:26.370 に答える