34

WebSocket API を使用して大きなファイル (少なくとも 500MB、できれば数 GB まで) をアップロードしようとしています。問題は、「ファイルのこのスライスを送信し、使用したリソースを解放してから繰り返す」という書き方がわからないことです。これには Flash/Silverlight のようなものを使用しないようにしたいと考えていました。

現在、私は次のようなことに取り組んでいます。

function FileSlicer(file) {
    // randomly picked 1MB slices,
    // I don't think this size is important for this experiment
    this.sliceSize = 1024*1024;  
    this.slices = Math.ceil(file.size / this.sliceSize);

    this.currentSlice = 0;

    this.getNextSlice = function() {
        var start = this.currentSlice * this.sliceSize;
        var end = Math.min((this.currentSlice+1) * this.sliceSize, file.size);
        ++this.currentSlice;

        return file.slice(start, end);
    }
}

次に、次を使用してアップロードします。

function Uploader(url, file) {
    var fs = new FileSlicer(file);
    var socket = new WebSocket(url);

    socket.onopen = function() {
        for(var i = 0; i < fs.slices; ++i) {
            socket.send(fs.getNextSlice()); // see below
        }
    }
}

基本的に、これはすぐに返され、bufferedAmount は変更されず (0)、送信を試行する前にすべてのスライスを繰り返してキューに追加し続けます。適切にキューに入れることができる socket.afterSend がありません。

4

6 に答える 6

10

大きなファイルの処理には、メイン スレッドで行う代わりに Web ワーカーを使用し、.xml を使用してファイル データのチャンクをアップロードしますfile.slice()

この記事は、ワーカーで大きなファイルを処理するのに役立ちます。メインスレッドで XHR が Websocket に送信されるように変更します。

//Messages from worker
function onmessage(blobOrFile) {
 ws.send(blobOrFile);
}

//construct file on server side based on blob or chunk information.
于 2014-06-27T06:08:17.760 に答える
10

メソッドsend()は非同期であるため、すぐに返されます。キューに入れるには、各スライスがアップロードされた後にサーバーがクライアントにメッセージを送り返す必要があります。クライアントは、次のスライスを送信する必要があるか、「アップロード完了」メッセージをサーバーに返す必要があるかを判断できます。

この種のことは、おそらく XMLHttpRequest(2) を使用すると簡単になります。コールバック サポートが組み込まれており、WebSocket API よりも広くサポートされています。

于 2012-06-18T09:47:15.263 に答える
5

この操作をシリアル化するには、スライスが受信および書き込まれる (またはエラーが発生する) たびにサーバーがシグナルを送信する必要があります。この方法では、onmessageイベントに応答して次のスライスを送信できます。次のようになります。

function Uploader(url, file) {
    var fs = new FileSlicer(file);
    var socket = new WebSocket(url);

    socket.onopen = function() {
       socket.send(fs.getNextSlice());
    }
    socket.onmessage = function(ms){
        if(ms.data=="ok"){
           fs.slices--;
           if(fs.slices>0) socket.send(fs.getNextSlice());
        }else{
           // handle the error code here.
        }
    }
}
于 2013-08-25T19:53:13.913 に答える
4

編集:この回答が作成されて以来、Webの世界、ブラウザ、ファイアウォール、プロキシは大きく変化しました。現在、WebSocket を使用したファイルの送信は、特にローカル エリア ネットワーク上で効率的に行うことができます。

Websocket は双方向通信に非常に効率的です。特に、サーバーから情報 (できれば小さなもの) をプッシュすることに関心がある場合はそうです。それらは双方向ソケットとして機能します (したがって、その名前が付けられています)。

Websocket は、この状況で使用するのに適したテクノロジではないようです。特に、それらを使用すると、一部のプロキシ、ブラウザー (IE)、さらにはファイアウォールとの非互換性が追加されることを考えると.

一方、ファイルのアップロードは、本体にファイルを含む POST 要求をサーバーに送信するだけです。ブラウザはそれが得意で、大きなファイルのオーバーヘッドはほとんどありません。そのタスクには WebSocket を使用しないでください。

于 2012-06-18T10:56:55.823 に答える
3

サーバーで node.js を実行できる場合は、 https ://github.com/binaryjs/binaryjsまたはhttps://github.com/liamks/Delivery.jsを使用できます。

于 2013-07-03T17:47:22.440 に答える