使用原生nodejs完成简易服务端功能(流、压缩、router)

>什么是流  

  任何连续的数据都叫流:文件流、网络流、音频流  

>使用流有什么好处

 传统文件处理,一般是先将文件读取进内存,然后使用内存中的数据 。而系统在进行读取过程中,使用数据的模块会处于闲置状态;

 当读取完毕进入使用数据状态时,读取数据模块又会进入闲置状态,这样就必然不能充分使用系统资源。如果数据本身过大,也会占

用大量内存空间。流会以读一部分处理一部分的形式处理数据,读取数据模块和处理数据模块都在同时工作,充分利用了系统资源。

读完的内存空间可以立即释放,占用的内存空间也仅是一小块而已。

>nodejs中使用流

 

 1 const fs = require('fs');
 2 
 3 //创建读取流
 4 let rs = fs.createReadStream('./www/1.html');
 5 
 6 //创建写入流
 7 let ws = fs.createWriteStream('./www/3.html');
 8 
 9 //将读取流连接写入流(读取流在前面)
10 rs.pipe(ws);
11 
12 rs.on('end',() => {
13   console.log('读取完毕');
14 });
15 
16 rs.on('error',err => {
17   console.log('读取出错' + err);
18 });
19 
20 ws.on('finish',() => {
21   console.log('写入完毕');
22 });
23 
24 ws.on('error',err => {
25   console.log('写入出错' + err);
26 });                                                

 

>使用压缩有什么好处

  压缩能够将一个原大小为50k的html压缩成1K大小,然后发送给浏览器,再通过Content-Encoding='gzip'的方式呈现页面,这样就能极大的节约网络带宽

  

 1 const http = require('http');
 2 const fs = require('fs');
 3 const zlib = require('zlib');
 4 const url = require('url');
 5 
 6 http.createServer((req,res) => {
 7   let {pathname,query} = url.parse(req.url,true);
 8 
 9   //创建读取流
10   let rs = fs.createReadStream(`./www${pathname}`);
11   //创建gzip对象
12   let gz = zlib.createGzip();
13 
14   //设置Content-Encoding为zlib
15   res.setHeader('Content-Encoding','gzip');
16 
17   //将读取流连接gz再连接Response对象(response对象也是流的一种)
18   rs.pipe(gz).pipe(res);
19 
20 }).listen(8081);

在这里,.pipe()方法会自动帮助我们监听data和end事件。上面的这段代码不仅简洁,而且请求文件中每一小段数据都将源源不断的发送到客户端,而非统一读取统一发送的形式。

>router

 当浏览器端发送请求时,服务器端需要知道请求的是接口还是文件,以便进行相应的处理。思路为使用EventEmitter对象判断监听是否存在,存在则为接口,不存在则为文件

 router.js代码内容:

1 //由于监听和触发分别处于两个不同的js文件,我们要保证程序运行中只能有一个EventEmitter
2 //对象,所以需要使用单例模式
3 const Event = require('events').EventEmitter;
4 
5 module.exports = new Event();

接口代码内容:

 1 const router = require('../../libs/router');
 2 
 3 let users = {};
 4 
 5 //监听login接口
 6 router.on('/login',(req,res) => {
 7  //接口内部代码忽略    
 8 });
 9 
10 //监听reg接口
11 router.on('/reg',(req,res) => {
12  //接口内部代码忽略    
13 });

主程序代码内容:

 1 const http = require('http');
 2 const url = require('url');
 3 const emitter = require('./libs/router');
 4 const user = require('./routers/user'); //这里引用接口js文件,确保emit与on同时存在
 5 
 6 http.createServer((req,res) => {
 7   let {pathname,query} = url.parse(req.url,true);
 8 
 9   //EventEmitter对象有监听(on)以及触发(emit)方法,只需要先提前实现所有监听接口(on),
10   //再通过是否已触发(emit)来判断该请求是接口还是文件类型
11   
12   //文件类型
13   if(emitter.emit(pathname,req,res) == false){
14     //文件类型,使用上面介绍的流的方式进行压缩传输处理    
15   }else{
16     //由于if语句中实现了触发动作,如果emitter.emit(pathname,req,res)==true,
17     //会自动执行user模块相应的接口代码,所以这里不需要处理
18   }
19 
20 }).listen(8081);

 

至此,一个最简单的原生nodejs服务端就编写完成了

posted @ 2018-02-06 00:16  cocoaVi  阅读(246)  评论(0)    收藏  举报