>

作者在阅读,创制八个服务器能依附不一样的u

- 编辑:至尊游戏网站 -

作者在阅读,创制八个服务器能依附不一样的u

自己在翻阅 NodeJS 文书档案中读出的十多个套路

2016/11/21 · JavaScript · NodeJS

原来的书文出处爬山涉水 David Gilbertson   译文出处爬山涉水王下邀月熊_Chevalier   

虽说自己早就用了三年多的NodeJS,也早已以为自身对其全知全能。可是自身临近未有有安静的坐下来留意地读书NodeJS的完整文书档案。倘若有纯熟本人的相爱的人应该驾驭,笔者事先已经看了HTML,DOM,Web APIs,CSS,SVG以至ECMAScript的文书档案,NodeJS是自个儿这些种类的最终叁个待翻阅的山峰。在阅读文书档案的进度中本人也发觉了无数本来不晓得的学识,小编以为我有必不可缺分享给我们。然则文书档案越多的是平淡无奇,由此笔者也以读书的次第列举出自己感觉需求精通的点。

1.小知识点总括

querystring:可以充当通用分析器的模块

重重时候大家会从数据库或其余地点获得这种离奇格式的字符串:name:Sophie;shape:fox;condition:new,通常的话大家会选择字符串切割的窍门来说字符串划分到JavaScript Object。但是querystring也是个不利的现有的工具:

JavaScript

const weirdoString = `name:Sophie;shape:fox;condition:new`; const result = querystring.parse(weirdoString, `;`, `:`); // result: // { // name: `Sophie`, // shape: `fox`, // condition: `new`, // };

1
2
3
4
5
6
7
8
const weirdoString = `name:Sophie;shape:fox;condition:new`;
const result = querystring.parse(weirdoString, `;`, `:`);
// result:
// {
//   name: `Sophie`,
//   shape: `fox`,
//   condition: `new`,
// };

* Xshell 使用open展开三个虚构机;

V8 Inspector

--inspect参数运维你的Node应用程序,它会反馈你某些U卡宴L。将该UEscortL复制到Chrome中并张开,你就足以运用Chrome DevTools来调整你的Node应用程序啦。详细的实验能够仿照效法那篇文章。可是须求小心的是,该参数如故属于实验性质。
图片 1

* linux 中创设三个空白的日记文件用touch命令;

nextTick 与 setImmediate的区别

这两货的区分恐怕光从名字上还看不出来,小编认为应该给它们取个别名:

  • process.nextTick()应该为process.sendThisToTheStartOfTheQueue()
  • setImmediate应该为sendThisToTheEndOfTheQueue()

再说句不相干的,React中的Props应为stuffThatShouldStayTheSameIfTheUserRefreshes,而State应该为stuffThatShouldBeForgottenIfTheUserRefreshes

* http 是nodejs的劳务模块

Server.listen 能够应用Object作为参数

自己更赏识命名参数的不二诀窍调用函数,这样相较于仅遵照顺序的无命名参数法会越来越直观。别忘了Server.listen也得以选取某些Object作为参数:

JavaScript

require(`http`) .createServer() .listen({ port: 8080, host: `localhost`, }) .on(`request`, (req, res) => { res.end(`Hello World!`); });

1
2
3
4
5
6
7
8
9
require(`http`)
  .createServer()
  .listen({
    port: 8080,
    host: `localhost`,
  })
  .on(`request`, (req, res) => {
    res.end(`Hello World!`);
  });

可是那么些特点不是公布在http.Server其如日中天API中,而是在其父级net.Server的文书档案中。

* fs 是文本服务器模块

相持地址

你传入fs模块的间隔能够是相对地址,即相对于process.cwd()。推测某一个人曾经知道了,可是自个儿事先一贯以为是只好采纳相对化地址:

JavaScript

const fs = require(`fs`); const path = require(`path`); // why have I always done this... fs.readFile(path.join(__dirname, `myFile.txt`), (err, data) => { // do something }); // when I could just do this? fs.readFile(`./path/to/myFile.txt`, (err, data) => { // do something });

1
2
3
4
5
6
7
8
9
10
const fs = require(`fs`);
const path = require(`path`);
// why have I always done this...
fs.readFile(path.join(__dirname, `myFile.txt`), (err, data) => {
  // do something
});
// when I could just do this?
fs.readFile(`./path/to/myFile.txt`, (err, data) => {
  // do something
});

* url是url路由模块

Path Parsing:路线剖析

事先本尘寰接不亮堂的有个别意义就是从有个别文件名中剖判出路线,文件名,文件扩张等等:

JavaScript

myFilePath = `/someDir/someFile.json`; path.parse(myFilePath).base === `someFile.json`; // true path.parse(myFilePath).name === `someFile`; // true path.parse(myFilePath).ext === `.json`; // true

1
2
3
4
myFilePath = `/someDir/someFile.json`;
path.parse(myFilePath).base === `someFile.json`; // true
path.parse(myFilePath).name === `someFile`; // true
path.parse(myFilePath).ext === `.json`; // true

2.创建nodejs服务器;

Logging with colors

别忘了console.dir(obj,{colors:true})可以看到以不相同的色彩打字与印刷出键与值,那一点会大大扩张日志的可读性。

//定义主机IP常量名称

行使setInterval执行准期职分

本人爱不忍释使用setInterval来定时施行数据库清理职分,然则默许境况下在设有setInterval的时候NodeJS并不会脱离,你能够接纳如下的主意让Node沉睡:

JavaScript

const dailyCleanup = setInterval(() => { cleanup(); }, 1000 * 60 * 60 * 24); dailyCleanup.unref();

1
2
3
4
const dailyCleanup = setInterval(() => {
  cleanup();
}, 1000 * 60 * 60 * 24);
dailyCleanup.unref();

const ip = '192.168.0.102';

Use Signal Constants

若果你品味在NodeJS中杀死有个别进程,估算您用过如下语法:

JavaScript

process.kill(process.pid, `SIGTERM`);

1
process.kill(process.pid, `SIGTERM`);

以此没啥问题,可是既然第叁个参数同期能够使用字符串与整形变量,那么还不比采用全局变量呢:

JavaScript

process.kill(process.pid, os.constants.signals.SIGTERM);

1
process.kill(process.pid, os.constants.signals.SIGTERM);

//定义端口号

IP Address Validation

NodeJS中包罗内置的IP地址校验工具,这点足以防受你写额外的正则表明式:

JavaScript

require(`net`).isIP(`10.0.0.1`) 返回 4 require(`net`).isIP(`cats`) 返回 0

1
2
require(`net`).isIP(`10.0.0.1`) 返回 4
require(`net`).isIP(`cats`) 返回 0

const port = 2000;

os.EOF

不领悟你有没有手写过行甘休符,看上去可不精粹啊。NodeJS内置了os.EOF,其在Windows下是rn,别的地点是n,使用os.EOL能够让你的代码在分化的操作系统上保障意气风发致性:

JavaScript

const fs = require(`fs`); // bad fs.readFile(`./myFile.txt`, `utf8`, (err, data) => { data.split(`rn`).forEach(line => { // do something }); }); // good const os = require(`os`); fs.readFile(`./myFile.txt`, `utf8`, (err, data) => { data.split(os.EOL).forEach(line => { // do something }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const fs = require(`fs`);
// bad
fs.readFile(`./myFile.txt`, `utf8`, (err, data) => {
  data.split(`rn`).forEach(line => {
    // do something
  });
});
// good
const os = require(`os`);
fs.readFile(`./myFile.txt`, `utf8`, (err, data) => {
  data.split(os.EOL).forEach(line => {
    // do something
  });
});

//引进的建构立模型块  http、url、fs

HTTP 状态码

NodeJS帮大家放手了HTTP状态码及其描述,也便是http.STATUS_CODES,键为状态值,值为描述:
图片 2

您能够信守如下方法应用:

JavaScript

someResponse.code === 301; // true require(`http`).STATUS_CODES[someResponse.code] === `Moved Permanently`; // true

1
2
someResponse.code === 301; // true
require(`http`).STATUS_CODES[someResponse.code] === `Moved Permanently`; // true

const http = require('http');

防止万分崩溃

有时碰到如下这种导致服务端崩溃的图景依然挺无语的:

JavaScript

const jsonData = getDataFromSomeApi(); // But oh no, bad data! const data = JSON.parse(jsonData); // Loud crashing noise.

1
2
const jsonData = getDataFromSomeApi(); // But oh no, bad data!
const data = JSON.parse(jsonData); // Loud crashing noise.

自家为了防止这种情景,在全局加上了一个:

JavaScript

process.on(`uncaughtException`, console.error);

1
process.on(`uncaughtException`, console.error);

本来,这种格局绝不是顶尖执行,假若是在大型项目中自个儿要么会动用PM2,然后将享有十分的大可能率崩溃的代码出席到try...catch中。

const url = require('url');

Just this once()

除了on方法,once方式也适用于拥有的伊芙ntEmitters,希望我不是最终才明白这些的:

JavaScript

server.once(`request`, (req, res) => res.end(`No more from me.`));

1
server.once(`request`, (req, res) => res.end(`No more from me.`));

const fs = require('fs');

Custom Console

你能够行使new console.Console(standardOut,errorOut),然后设置自定义的输出流。你能够筛选创设console将数据输出到文件只怕Socket只怕第三方中。

//创立一个服务

DNS lookup

某个年轻人告诉自身,Node并不会缓存DNS查询消息,由此你在选拔URL之后要等个几微秒技能赢获得数量。但是事实上您能够行使dns.lookup()来缓存数据:

JavaScript

dns.lookup(`www.myApi.com`, 4, (err, address) => { cacheThisForLater(address); });

1
2
3
dns.lookup(`www.myApi.com`, 4, (err, address) => {
  cacheThisForLater(address);
});

var server = http.createServer(function(req,res){

fs 在差异OS上有一定间隔

  • fs.stats()重临的目的中的mode性子在Windows与别的操作系统中留存差别。
  • fs.lchmod()仅在macOS中有效。
  • 仅在Windows中援助调用fs.symlink()时使用type参数。
  • 仅仅在macOS与Windows中调用fs.watch()时传入recursive选项。
  • 在Linux与Windows中fs.watch()的回调能够流传某些文件名
  • 使用fs.open()以及a+质量张开某些目录时唯有在FreeBSD以致Windows上起成效,在macOS以致Linux上则设有难题。
  • 在Linux下以充实格局展开某些文件时,传入到fs.write()position参数会被忽略。

res.writeHead(200,{'Content-Type':'text/plain'});

net 模块差不离比http快上两倍

作者在文书档案中观望局地关于两岸质量的研商,还专程运维了五个服务器来进行小心稳重相比较。结果来看http.Server粗粗每秒能够连接3400个伏乞,而net.Server能够接入大致5500个央求。

JavaScript

// This makes two connections, one to a tcp server, one to an http server (both in server.js) // It fires off a bunch of connections and times the response // Both send strings. const net = require(`net`); const http = require(`http`); function parseIncomingMessage(res) { return new Promise((resolve) => { let data = ``; res.on(`data`, (chunk) => { data += chunk; }); res.on(`end`, () => resolve(data)); }); } const testLimit = 5000; /* ------------------ */ /* -- NET client -- */ /* ------------------ */ function testNetClient() { const netTest = { startTime: process.hrtime(), responseCount: 0, testCount: 0, payloadData: { type: `millipede`, feet: 100, test: 0, }, }; function handleSocketConnect() { netTest.payloadData.test++; netTest.payloadData.feet++; const payload = JSON.stringify(netTest.payloadData); this.end(payload, `utf8`); } function handleSocketData() { netTest.responseCount++; if (netTest.responseCount === testLimit) { const hrDiff = process.hrtime(netTest.startTime); const elapsedTime = hrDiff[0] * 1e3 + hrDiff[1] / 1e6; const requestsPerSecond = (testLimit / (elapsedTime / 1000)).toLocaleString(); console.info(`net.Server handled an average of ${requestsPerSecond} requests per second.`); } } while (netTest.testCount < testLimit) { netTest.testCount++; const socket = net.connect(8888, handleSocketConnect); socket.on(`data`, handleSocketData); } } /* ------------------- */ /* -- HTTP client -- */ /* ------------------- */ function testHttpClient() { const httpTest = { startTime: process.hrtime(), responseCount: 0, testCount: 0, }; const payloadData = { type: `centipede`, feet: 100, test: 0, }; const options = { hostname: `localhost`, port: 8080, method: `POST`, headers: { 'Content-Type': `application/x-www-form-urlencoded`, }, }; function handleResponse(res) { parseIncomingMessage(res).then(() => { httpTest.responseCount++; if (httpTest.responseCount === testLimit) { const hrDiff = process.hrtime(httpTest.startTime); const elapsedTime = hrDiff[0] * 1e3 + hrDiff[1] / 1e6; const requestsPerSecond = (testLimit / (elapsedTime / 1000)).toLocaleString(); console.info(`http.Server handled an average of ${requestsPerSecond} requests per second.`); } }); } while (httpTest.testCount < testLimit) { httpTest.testCount++; payloadData.test = httpTest.testCount; payloadData.feet++; const payload = JSON.stringify(payloadData); options[`Content-Length`] = Buffer.byteLength(payload); const req = http.request(options, handleResponse); req.end(payload); } } /* -- Start tests -- */ // flip these occasionally to ensure there's no bias based on order setTimeout(() => { console.info(`Starting testNetClient()`); testNetClient(); }, 50); setTimeout(() => { console.info(`Starting testHttpClient()`); testHttpClient(); }, 2000);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// This makes two connections, one to a tcp server, one to an http server (both in server.js)
// It fires off a bunch of connections and times the response
 
// Both send strings.
 
const net = require(`net`);
const http = require(`http`);
 
function parseIncomingMessage(res) {
  return new Promise((resolve) => {
    let data = ``;
 
    res.on(`data`, (chunk) => {
      data += chunk;
    });
 
    res.on(`end`, () => resolve(data));
  });
}
 
const testLimit = 5000;
 
 
/*  ------------------  */
/*  --  NET client  --  */
/*  ------------------  */
function testNetClient() {
  const netTest = {
    startTime: process.hrtime(),
    responseCount: 0,
    testCount: 0,
    payloadData: {
      type: `millipede`,
      feet: 100,
      test: 0,
    },
  };
 
  function handleSocketConnect() {
    netTest.payloadData.test++;
    netTest.payloadData.feet++;
 
    const payload = JSON.stringify(netTest.payloadData);
 
    this.end(payload, `utf8`);
  }
 
  function handleSocketData() {
    netTest.responseCount++;
 
    if (netTest.responseCount === testLimit) {
      const hrDiff = process.hrtime(netTest.startTime);
      const elapsedTime = hrDiff[0] * 1e3 + hrDiff[1] / 1e6;
      const requestsPerSecond = (testLimit / (elapsedTime / 1000)).toLocaleString();
 
      console.info(`net.Server handled an average of ${requestsPerSecond} requests per second.`);
    }
  }
 
  while (netTest.testCount < testLimit) {
    netTest.testCount++;
    const socket = net.connect(8888, handleSocketConnect);
    socket.on(`data`, handleSocketData);
  }
}
 
 
/*  -------------------  */
/*  --  HTTP client  --  */
/*  -------------------  */
function testHttpClient() {
  const httpTest = {
    startTime: process.hrtime(),
    responseCount: 0,
    testCount: 0,
  };
 
  const payloadData = {
    type: `centipede`,
    feet: 100,
    test: 0,
  };
 
  const options = {
    hostname: `localhost`,
    port: 8080,
    method: `POST`,
    headers: {
      'Content-Type': `application/x-www-form-urlencoded`,
    },
  };
 
  function handleResponse(res) {
    parseIncomingMessage(res).then(() => {
      httpTest.responseCount++;
 
      if (httpTest.responseCount === testLimit) {
        const hrDiff = process.hrtime(httpTest.startTime);
        const elapsedTime = hrDiff[0] * 1e3 + hrDiff[1] / 1e6;
        const requestsPerSecond = (testLimit / (elapsedTime / 1000)).toLocaleString();
 
        console.info(`http.Server handled an average of ${requestsPerSecond} requests per second.`);
      }
    });
  }
 
  while (httpTest.testCount < testLimit) {
    httpTest.testCount++;
    payloadData.test = httpTest.testCount;
    payloadData.feet++;
 
    const payload = JSON.stringify(payloadData);
 
    options[`Content-Length`] = Buffer.byteLength(payload);
 
    const req = http.request(options, handleResponse);
    req.end(payload);
  }
}
 
/*  --  Start tests  --  */
// flip these occasionally to ensure there's no bias based on order
setTimeout(() => {
  console.info(`Starting testNetClient()`);
  testNetClient();
}, 50);
 
setTimeout(() => {
  console.info(`Starting testHttpClient()`);
  testHttpClient();
}, 2000);

JavaScript

// This sets up two servers. A TCP and an HTTP one. // For each response, it parses the received string as JSON, converts that object and returns a string const net = require(`net`); const http = require(`http`); function renderAnimalString(jsonString) { const data = JSON.parse(jsonString); return `${data.test}: your are a ${data.type} and you have ${data.feet} feet.`; } /* ------------------ */ /* -- NET server -- */ /* ------------------ */ net .createServer((socket) => { socket.on(`data`, (jsonString) => { socket.end(renderAnimalString(jsonString)); }); }) .listen(8888); /* ------------------- */ /* -- HTTP server -- */ /* ------------------- */ function parseIncomingMessage(res) { return new Promise((resolve) => { let data = ``; res.on(`data`, (chunk) => { data += chunk; }); res.on(`end`, () => resolve(data)); }); } http .createServer() .listen(8080) .on(`request`, (req, res) => { parseIncomingMessage(req).then((jsonString) => { res.end(renderAnimalString(jsonString)); }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// This sets up two servers. A TCP and an HTTP one.
// For each response, it parses the received string as JSON, converts that object and returns a string
const net = require(`net`);
const http = require(`http`);
 
function renderAnimalString(jsonString) {
  const data = JSON.parse(jsonString);
  return `${data.test}: your are a ${data.type} and you have ${data.feet} feet.`;
}
 
 
/*  ------------------  */
/*  --  NET server  --  */
/*  ------------------  */
 
net
  .createServer((socket) => {
    socket.on(`data`, (jsonString) => {
      socket.end(renderAnimalString(jsonString));
    });
  })
  .listen(8888);
 
 
/*  -------------------  */
/*  --  HTTP server  --  */
/*  -------------------  */
 
function parseIncomingMessage(res) {
  return new Promise((resolve) => {
    let data = ``;
 
    res.on(`data`, (chunk) => {
      data += chunk;
    });
 
    res.on(`end`, () => resolve(data));
  });
}
 
http
  .createServer()
  .listen(8080)
  .on(`request`, (req, res) => {
    parseIncomingMessage(req).then((jsonString) => {
      res.end(renderAnimalString(jsonString));
    });
  });

res.write('my nodejs');

REPL tricks

  • 比如您是在REPL情势下,正是直接输入node然后步入互相状态的格局。你能够一直输入.load someFile.js下一场可以载入包涵自定义常量的文本。
  • 能够通过设置NODE_REPL_HISTORY=""来制止将日志写入到文件中。
  • _用来记录最终贰个总括值。
  • 在REPL运转未来,全体的模块都曾经间接加载成功。可以行使os.arch()而不是require(os).arch()来使用。

    1 赞 3 收藏 评论

图片 3

res.end();

});

//监听一个端口

server.listen(port,ip,function(){

console.log('server start');

});

3.得到U君越L部分块的原委 url;

const ip = '192.168.1.118';//主机IP

const port = 2001;//端口号

//引进的建立立模型块  http、url、fs

const http = require('http');

const url = require('url');

const fs = require('fs');

//创建服务的回掉函数

var funSer = function(req,res){

//获取url地址块的内容  如跋山涉水的近义词/path/show

var parth = url.parse(req.url).pathname;

res.write(parth);

res.end();

}

//监听端口的回掉

var fun = function(){

console.log('server start');

}

var server = http.createServer(funSer).listen(port,ip,fun);

4.读取文件的剧情 File System;

const ip = '192.168.1.118';//主机IP

const port = 2001;//端口号

//引入的建构立模型块  http、url、fs

const http = require('http');

const url = require('url');

const fs = require('fs');

//真正打字与印刷文件内容

fs.readFile('./index.html', (err, data) => {

if (err) throw err;

//打印字符串内容

console.log(data.toString());

});

//创造服务的回掉函数

var funSer = function(req,res){

//获取url地址块的剧情  如爬山涉水/path/show

var parth = url.parse(req.url).pathname;

res.write(parth);

res.end();

}

//监听端口的回掉

var fun = function(){

console.log('server start');

}

var server = http.createServer(funSer).listen(port,ip,fun);

  1. 全体实例(依照区别的url地址央求例外的文本【模板】)

const ip = '192.168.1.118';//主机IP

const port = 2001;//端口号

//引进的组装模块  http、url、fs

const http = require('http');

const url = require('url');

const fs = require('fs');

//实例化贰个劳务容器

var server = new http.Server();

//监听贰个端口

server.listen(port , ip);

//注册多个事件管理的on方法

server.on('request' , function(req , res){

//获取央浼的url地址

var url = urls.parse(req.url);

//console.log(url.pathname);

//按照path路线来读取不相同的模版文件

switch( url.pathname ){

case '' || '/':

//读取文件内容

fs.readFile('./index.html',function( error, content){

if(error){//假设有不那时候,展现错误音信

res.writeHead(400,{'Content-Type':'text/plain;charset="utf-8"'});

res.write(error.message);

res.end();

}else{

//正确时浏览器输出模板文件的情节

res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});//头信息

res.write(content);//模板文件内容

res.end();

}

});

break;

case '/list':

fs.readFile('./list.html',function( error, content){

if(error){

res.writeHead(400,{'Content-Type':'text/plain;charset="utf-8"'});

res.write(error.message);

res.end();

}else{

res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});

res.write(content);

res.end();

}

});

break;

case '/show':

fs.readFile('./show.html',function( error, content){

if(error){

res.writeHead(400,{'Content-Type':'text/plain;charset="utf-8"'});

res.write(error.message);

res.end();

}else{

res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});

res.write(content);

res.end();

}

});

break;

default:

fs.readFile('./default.html',function( error, content){

if(error){

res.writeHead(400,{'Content-Type':'text/plain;charset="utf-8"'});

res.write(error.message);

res.end();

}else{

res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});

res.write(content);

res.end();

}

});

break;

}

});

本文由软件综合发布,转载请注明来源:作者在阅读,创制八个服务器能依附不一样的u