LiteHub之文件下载与视频播放
文件下载
前端请求
箭头函数
1 | //这个箭头函数可以形象理解为,x流入(=>)x*x, |
本项目的请求下载前端代码为:
1 | function downloadFile(resourceId, filename, progressBar, statusText) { |
对于pump
函数的理解,结合箭头函数和promise
- reader.read()
○ 返回一个 Promise<{ done: boolean, value: Uint8Array }>。
○ done: true 表示读取完了;
○ value 是当前读取的一段数据(Uint8Array 格式)。 - 箭头函数 () => reader.read().then(…)
○ 这是一个返回 Promise 的函数。
○ done: true 表示读取完了;
○ value 是当前读取的一段数据(Uint8Array 格式)。 - 箭头函数 () => reader.read().then(({ done, value }) => { return dump()}
■ ()=>reader.read(),无参数传入,执行reader.read(),返回reader.read()执行的结果{done,value}。
■ .then({ done, value })通过上一步接收这两个数据,然后通过这两个执行相应内容;
■ 如果done为false,表示还没执行完成,chunks.push(value):把这一段加入缓存 ,更新进度条, 递归调用自身,继续下一段读取 (return pump())。
后端响应
1 | FileUtil file(filePath); |
设计亮点
在HttpResponse.h
头文件中
1 | public: |
在httpserver的请求函数中判断,如果是文件类型,就调用tcpconnection先将响应头发送出去,然后将消息体分小块发送,这里设置的是8kb;如果不是文件类型,直接将整个响应发送出去
在HttpServer::onRequest
函数中
1 | // 给response设置一个成员,判断是否请求的是文件,如果是文件设置为true,并且存在文件位置在这里send出去。 |
之所以是在httpserver上分块发送数据流,是为了保证代码较好的层次性,httpserver负责管理多个tcp连接,包括发送消息和接收消息等。
视频播放
1 | // 从请求中获取 Range 头,例如 "bytes=1000-2000" |
后端涉及对请求体中的range字段进行解析,判断range字段的合法性,随后根据range字段请求内容决定是返回部分内容还是全部内容。
请求所有内容:
依次拖动播放进度条,range字段发生改变,格式为
请求部分内容:
这里请求的是从字节6000-18000大小的数据,返回的响应为
这里的响应头字段为206 partial content
,表示响应返回的只是视频的一部分数据。
range的合法性校验
这里我手动指定range的范围为6000-18000000000000
,实际是超出了请求视频的最大范围,看看最后返回的什么。使用curl(这里因为是测试,所以去掉了权限的判定,实际上运行的时候使用curl是不可行的)
可以看到这里返回的是文件的最大大小。