前端用websocket, websocket server用的是php的swoole扩展。
几经探索,创造大略、靠谱、占内存少的大致流程是这样的:
每一个文件的准备事情【读取数据块之前】:

做事端保存完这些json数据,见告浏览器, \公众hi, 我保存好啦,你可以开始发送这个文件的数据块啦\"大众,浏览器才开始吭吭哧哧地读取第1个文件的第1个数据块。
做事端保存了这个数据块成功了,更新redis中的信息,包括:
已上传的大小,剩余大小下一个数据块的序号小文件的路径+文件名(如果是放在磁盘中)或者文件的fileId(如果用的MongoDB gridFs), 这这天后合并小文件的依据。这个文件是否传了全部的数据块, isFinish,$isFinish = $fileSize === $totalUploadSize;
如果为false, 则:
见告浏览器, :(例句)\公众hi, 我保存的是第20块的数据,还有57M须要上传\"大众。然后,浏览器开始读取这个文件的下一个数据块。否则:
见告浏览器, :例句)\"大众hi, 我保存的是第29块的数据,还有0Bit须要上传\"大众。然后,浏览器开始欢天喜地读取下一个文件的第1个数据块。为了测试分块上传后,文件是否还是原来的样子,我特意挑选视频(至少100M的那种)作为测试材料。
利用html api供应的FileReader工具, 读取文件的方法:
readAsText 方法 用于读取文本文件---限定了文件类型,没有考试测验,直接放弃。readAsDataURL 方法 返回一个data URL,它的浸染基本上是将文件数据进行Base64编码。你可以将返回值设为图像的src属性。----没有考试测验,直接放弃readAsBinaryString 方法 可以读取任意类型的文件,而不仅仅是文本文件。这个方法与XMLHttpRequest.sendAsBinary方法结合利用,就可以利用JavaScript上传任意文件到做事器。-----考试测验了,踩到坑了。。。readAsArrayBuffer方法读取文件,返回一个类型化数组(ArrayBuffer),即固定长度的二进制缓存数据。---考试测验了,切多少,读取到的数据便是多少,做事端按顺序合并为大文件后,体积不变,可以播放。一开始,也不懂,随着网上的大佬利用readAsArrayBuffer。
var reader = new FileReader();var blob = reader.slice(startSize, endSize);reader.readAsArrayBuffer(blob);reader.onload = function(e) { var arrayBuffer = e.target.result; }
如上,读取是异步非壅塞的,好有诱惑力。
我禁不住诱惑,在循环打算每一个数据块的startSize和endSize时,就运行读取操作,由于读取是异步非壅塞的->读取数据块是争先恐后的->哪一块先读取成功是不愿定的。
结果是,
我利用谷歌浏览器开拓者版,标签页还常常卡去世,掌握台中显示javascript占用了几百兆的内存!!
!
错上加错: 先发送json, 紧接着发送二进制数据,居然可以还原大文件,实在是由于,我的websocket server因此同步壅塞(即便利用协程也不过是半壅塞)的办法处理数据!
为了同时发json和文件数据,我考试测验了readAsBinaryString....我创造,切5M的数据,读取到的数据不止5M。做事端按顺序合并为大文件后,体历年夜了好多,无法播放。。。唉,都是泪呀。
又辗转回readAsArrayBuffer。
下一篇说说,如何用js获取文件的md5值, 这样,可以避免上传名称不同、文件内容相同的文件。
关于断点续传,我还在路上。。。