使用WebSocket上传大文件

时间:2012-06-18 09:27:31

标签: javascript html5 websocket large-files fileapi

我正在尝试使用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允许我正确排队,这就是我被困住的地方。

6 个答案:

答案 0 :(得分:10)

我相信send()方法是异步的,这就是为什么它会立即返回。要使其排队,您需要服务器在上传每个切片后将消息发送回客户端;然后,客户端可以决定是否需要将下一个片段或“上传完成”消息发送回服务器。

使用XMLHttpRequest(2)可能会更容易这样的事情;它内置了回调支持,并且比WebSocket API支持得更广泛。

答案 1 :(得分:7)

使用网络工作者进行大型文件处理,而不是在主线程中进行,并使用file.slice()上传文件数据块。

这个article可以帮助您处理工作人员中的大文件。将XHR发送到主线程中的Websocket。

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

//construct file on server side based on blob or chunk information.

答案 2 :(得分:5)

为了序列化此操作,您需要服务器在每次收到切片时向您发送信号&amp;写入(或发生错误),这样你就可以发送下一个片段来响应 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.
        }
    }
}

答案 3 :(得分:3)

编辑:网络世界,浏览器,防火墙,代理,自这个答案提出后发生了很大变化。现在,使用websockets发送文件 可以有效地完成,尤其是在局域网上。

Websockets对于双向通信非常有效,特别是当您有兴趣从服务器推送信息(最好是小)时。它们充当双向套接字(因此得名)。

Websockets似乎不适合在这种情况下使用。特别是考虑到使用它们会增加与某些代理,浏览器(IE)甚至防火墙的不兼容性。

另一方面,上传文件只是向服务器发送POST请求,文件在正文中。浏览器非常擅长,大文件的开销几乎没有。不要使用websockets来完成该任务。

答案 4 :(得分:3)

如果您可以在服务器上运行node.js,则可以使用https://github.com/binaryjs/binaryjshttps://github.com/liamks/Delivery.js

答案 5 :(得分:0)

我认为这个socket.io项目具有很大的潜力:

https://github.com/sffc/socketio-file-upload

它支持分块上传,进度跟踪,并且似乎非常易于使用。