我正在尝试使用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允许我正确排队,这就是我被困住的地方。
答案 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/binaryjs或https://github.com/liamks/Delivery.js。
答案 5 :(得分:0)