节点实现分片下载的示例代码

  

本文基于http请求范围协议,实现了分片下载的功能。

  

使用场景包括基于浏览器的流文件片段传输,基于客户端的分片下载等。

  

<强>原理

  

http通过请求范围相关的头,可以与服务器进行协商,实现分部分的请求。

  

这里就不细说具体协议内容了,具体可以参考这两篇文章,解释的非常详细:

  
      <李> https://tools.ietf.org/html/rfc7233   <李> https://www.jb51.net/article/68284.htm   
  

下面贴一下实现过程。

  

<>强服务端代码

  

服务端用节点实现:

        app.use(异步ctx=比;{   常量文件=路径。加入(__dirname“$ {PATH} $ {ctx.path}”);//1404检查   尝试{   fs.accessSync(文件);   }捕捉(e) {   ctx.response返回。状态=404;   }   常量方法=ctx.request.method;   const{大小}=fs.statSync(文件);//2、响应头请求,返回文件大小   如果(“头”==方法){   ctx返回。集(内容长度,大小);   }   常量范围=ctx.headers(的范围);//3、通知浏览器可以进行分部分请求   如果范围(!){   ctx返回。设置(“Accept-Ranges”、“字节”);   }   const{开始,结束}=getRange(范围);//4、检查请求范围   如果(开始在大?| |结束祝辞=大小){   ctx.response。状态=416;   ctx返回。集(“含量”、“字节*/${大小}”);   }//5206分部分响应   ctx.response。状态=206;   ctx。设置(“Accept-Ranges”、“字节”);   ctx。设置(“含量”、“字节{开始}-{美元结束& # 63;结束:尺寸- 1}/${大小}');   ctx。身体=fs。createReadStream(文件,{开始,结束});   });      app.listen(3000年,()=比;控制台。日志(部分内容服务器开始'));      函数getRange(范围){   var=/字节=匹配([0 - 9]*)- ([0 - 9]*)/.exec(范围);   const requestRange={};   如果(匹配){   如果requestRange(匹配[1])。比赛开始=数量([1]);   如果requestRange(匹配[2])。结束=数量(匹配[2]);   }   返回requestRange;   }      

代码实现的功能逻辑大致是:

  
      <李>对请求的资源做检查,不存在则响应404年李   <李>对于头请求,返回资源大小李   <李>如果得到请求没有告知范围,返回内容长度,告知浏览器可以进行分片请求李   <李>如果请求设置了范围,则检查范围是否合法,不合法返回合法的rangge李   <李>一切正常,获取文件范围范围部分,做流响应李   
  

代码很简单,把范围请求协议对应实现一遍就好了,当然这里没有完全实现协议的内容,但已经满足了这里演示的需求。

  

服务端代码好了,用一个浏览器的演示来检验一下。

  

<强>浏览器例子

  

现代浏览器基本都实现了范围的请求,这里用音频标签作为例子。

        & lt; html>   & lt; head>   & lt; title>分片流传输& lt;/title>   & lt;脚本type=" text/javascript祝辞   函数跳转(){   const球员=. getelementbyid (“musicPlayer”);//从30年代开始播放   的球员。currentTime=30;   }   & lt;/script>   & lt;/head>   & lt; body>   & lt;音频id=" musicPlayer " src=" https://www.yisu.com/zixun/http 127.0.0.1:3000/source.mp3”controls> & lt;/audio>   & lt; button>切到30 s   & lt;/body>   & lt;/html>      

最终的效果是这样的:

  

节点实现分片下载的示例代码”> <br/>
  </p>
  <p> <img src=

  

对比两张图,当html加载完成,浏览器自动请求资源,此时头有<代码>范围:字节=0 -> 范围:字节=3145728 ->   

同样用这个服务端代码,还可以实现一个客户端,模拟一下分包下载。

  

<强>节点分包下载

  

这个例子演示了,对一个资源,并发的实现分部分的下载,然后再合并成一个文件。

  

这里也是用节点实现:

        从“请求”进口请求;   从“路径”导入路径;   进口fs“fs”;      const单=1024 * 1000;   const源=' http://127.0.0.1:3000 source.mp3 ';      请求({   方法:“头”,   uri:源,   },(呃,res)=比;{   如果(err)返回console.error(错);   常量文件=路径。加入(__dirname。/下载/source.mp3);   尝试{   fs.closeSync (fs。openSync(文件、' w '));   }捕捉(err) {   返回console.error (err);   }   常量大?数量(res.headers['内容长度']);   const长度=方法(大?单);   (让我=0;i

节点实现分片下载的示例代码