首页 » Web前端 » php下发多个文件技巧_前端websocket分块分段上传多个大年夜文件

php下发多个文件技巧_前端websocket分块分段上传多个大年夜文件

访客 2024-12-19 0

扫一扫用手机浏览

文章目录 [+]

前端用websocket, websocket server用的是php的swoole扩展。

几经探索,创造大略、靠谱、占内存少的大致流程是这样的:

php下发多个文件技巧_前端websocket分块分段上传多个大年夜文件

读取数据块->发送数据块->等待做事端保存完毕->读取下一个数据块->发送数据块->等待做事端保存完毕->...文件a, 读取末了一个数据块->发送数据块->等待做事端保存完毕。
承上启下的重头戏:浏览器端, 文件b, 读取第1个数据块->发送数据块->等待做事端保存完毕->读取下一个数据块->发送数据块->等待做事端保存完毕->...做事端,worker主进程派发任务给taskWorker进程,由该进程将文件a的各个数据块按顺序合并为大文件。

每一个文件的准备事情【读取数据块之前】:

php下发多个文件技巧_前端websocket分块分段上传多个大年夜文件
(图片来自网络侵删)
算出:须要切成几块;算出:每一块的大小及其序号;加上文件名、文件大小、文件类型,以json格式一并发给做事端,这个是为了保存的是第几块的数据,还多少M须要上传;吸收到的二进制数据,是否跟当时读取的大小一样,万一,由于网络缘故原由,没有传全,可以丢弃,避免文件“变质”

做事端保存完这些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值, 这样,可以避免上传名称不同、文件内容相同的文件。

关于断点续传,我还在路上。


标签:

相关文章