NODEJS-基本库点滴

Assert:

  这个模块用于单元测试使用 require('assert') 之后可以使用;

  主要功能就是判断表达式的值,当表达式为假时可以抛出异常。

  assert.fail(actual, expected, message, operator)  ///函数比较actual于expected值相等时没有操作,否则抛出异常 message为空时格式为 acturl operator expected 方式,否则错误信息为message。
  assert(value, message), assert.ok(value, [message])
  assert.equal(actual, expected, [message])
  assert.deepEqual(actual, expected, [message])
  ///这些函数功能都类似。

BUFFER:

  该模块提供了缓存的处理能力,node自动加载Buffer类,因此不需要require;

  1)提供了编码的支持(注意binary方式将来要取消,因此尽量不要使用);将buffer转换成字符串时编码需要注意unicode问题,比如buf在unicode的边界时可能会丢数据。参考concat。

  2)Buffer的字节长度Buffer.byteLength,于字符串类的长度不同。

  var str = '中常手';

  console.log(str + ": " + str.length + " characters, " + Buffer.byteLength(str, 'utf8') + " bytes");

  注:字符串长度为3,而字节长度为9;

  3)Buffer.concat(list,[totalLength]) 将buffer列表连接成一个buffer,这个函数在data,end事件中非常有用.

  4) buf.copy(targeBuf...), buf.write, buf[index],buf.fill 四个读写函数

  5)读写数值类函数 buf.writeUInt32BE/LE, buf.readUInt32BE/LE 按照大端小端方式读写数值型,这些函数在实现协议中特别有用。

ChildProcess:

  1)子进程与进程间的通讯实现模块。每个node进程的process就是该类的实例。

  2)可以通过spawn,exec方式创建子进程,每个子进程都有stdout,stdin,stderr三个关联的流可用于读取. 另外通过send函数可以再父子进程之间进行通讯。

  3)process的pid属性表示进程ID,kill方法可以用于发送信号。

  4)关于发送消息,注意:消息属性中包含NODE_前缀将被理解为NODE保留消息,因此这种消息不会产生message事件通知;通过send来分享server对象,分享server然后父子进程同时在其上监听connect事件将导致父子分担处理新的连接;通过send分享socket对象,server监听端得到连接的socket后,可将socket传递给子进程处理,此时服务器将不再持有该socket(具体参考文档)。

Cluster:

  NODEjs中为了充分发挥多核系统的性能,提供了该模块。

  工作原理:master创建worker使用child process因此他们之间可以进行通讯。当worker调用server.listen时会将相关的参数发送到master,master检查参数若有匹配的handle则将其返回,否则master将创建一个并返回给worker。主要是为了多个worker之间能够协同工作,这样就不会导致第二个无法再同样端口上监听的问题。(注意:listen(0) 将会导致master在随机的端口上创建socket,因此若多个worker要共享端口则需要显示指定端口号来调用listen)。

  多个worker的负载问题,由于多个worker都在accept因此最终哪个成功有操作系统决定。

  另外由于worker互相独立因此再cluster中增加worker或者减少都不影响其他的worker处理新连接。

  cluster主要事件:fork事件(当子进程被创建出来后触发);online事件(子进程开始执行代码时触发);listening事件(worker进程调用listen时触发);disconnect事件(子进程挂掉后者调用disconnect函数);exit事件(子进程退出)。

Crypto:

  该模块用于处理加密,哈希以及https等认证信息。

Debugger:

  google的V8引擎中使用TCP协议内建了调速器,node在客户端中封装了一些命令。使用 node debug test.js 方式可以启动调试。

Dns:

  Dns解析模块,该模块中的解析函数除了lookup之外,其他都使用C-Ares异步方式解析。而lookup函数使用系统的getaddrinfo同步方式解析,当需要执行大量的DNS解析工作时应该采用C-Ares方式进行解析。

Events:

  NODE中的事件处理模块,node中所有释放事件的对象都为events.EventEmitter的实例。当事件触发时被执行的关联函数被称为listeners,在回调函数内部的this关联的是events.EventEmitter对象。

  若某个类需要支持事件,那么可以按照如下方式:

var EventEmitter = require('events').EventEmitter;
var util = require('util');

function TestEvent(){
    EventEmitter.apply(this);
}
util.inherits(TestEvent, EventEmitter);  ///这条语句必须在定义TestEvent.prototype之前执行,因为该条语句会重置prototype属性。
TestEvent.prototype.test = function(){ this.emit('event1','hahah'); }

  error事件,当事件对象发生异常时,通常释放error错误。node中对error事件有特别的处理,即若没有设置error事件的处理函数则默认node会打印堆栈并退出。

  另外还有增强型的eventproxy模块可以方便对事件的使用。

FS:

  NOD之中实现文件系统操作的模块。大多数函数都提供了同步与异步版本。甚至还提供了监视文件或者目录的函数。

Global:

  Global不是一个模块,只是将一些全局可用的对象或者类进行介绍。

  特别需要注意的是:NODE中每个模块都是一个顶层空间,因此一个模块中使用var方式定义的变量不会影响另一个模块。特别注意的是:若没有使用var定义则将污染全局空间。  

///module1.js 定义
zcs = 'zhongchangshou';


///module2.js定义
var module1 = require('./module1.js');
console.log(zcs);   ///将打印出 zhongchangshou

  另外,process、Buffer、require函数、__filename, __dirname 都是立即可用的。

  setTimeout, setInterval 函数也都可以使用,特别注意这两个函数的第一个参数为cb,而不是一条语句。  

HTTP:

1、http.createServer([requestistener]) 将创建一个 http.Server类(该类从EentEmitter类继承),其中到参数requestListener会被自动加入到 http.Server类到request事件处理列表之中.

2, http.Server 类从EentEmitter继承,定义了如下事件:

  2.1 Request 事件,每次有客户端请求时调用触发该事件(一个长连接可能会产生多个请求,触发多个事件), 事件原型如下:function (request, response) { }, 其中request为http.IncomingMessage类实例,而reqponse为http.ServerResponse类实例.

  2.2 Connection 事件,表示一个连接以及可以使用时触发,原型:function (socket) { }, 参数socket为net.Socket类实例, 该参数也可以通过 request.connection 成员来获取.

  2.3 Close 事件,当一个连接关闭时触发. 注意:连接和请求到关系,一个连接上可以有多个请求.

  2.4 checkContinue 事件,当收到客户端包含 100-continue 请求时触发该事件,若没有订阅该事件则服务器自动回复100-continue. 处理该事件时,若允许客户端继续发送数据,则使用 response.writeContinue ,否则返回一个具体到错误码. 事件原型:function (request, response) { }, 注意: 当该事件触发并被处理时,将不会再产生Request 事件.

  2.5 connect, upgrade事件,当客户端请求一个CONNECT方法(主要用于代理服务器与目标服务器之间建立连接)时会触发connect事件,请求upgrade时会出发upgrade事件,若服务端没有对这两个事件进行监听那么客户端的socket将被关闭

  2.6 listen函数

server.listen(port, [hostname], [backlog], [callback])

  比较需要注意的是,backlog参数默认可以达到系统的最大值511,而callback在监听成功时会被调用。

  2.7 两个有用的属性

server.maxHeadersCount  ///表示客户端发送请求中headers最大个数
server.timeout   ///客户端的连接默认多久超时,超时后将会触发 timeout事件,若没处理则关闭给socket

3, http.ServerResponse

  这个类由server端创建,并在request事件的第二个参数中传递。

  该类封装了对客户端的回复消息。

  http.ServerResponse 实现了Writeable Stream接口,因此可以想其中写入数据。

4, http.request

  该函数执行到服务器到一个请求,原型: http.request(options, callback) 其中到options指定到hostname,port,path 三个参数比较关键, 当要执行一个到指定url到请求时,需要使用url模块对其进行解析,如: url.parse(dlinfo.dlurl).host

5、http.Agent

  http客户端默认使用一个Agent,在http.request函数中可以使用 agent:false 的option来关闭agent的使用。

  Agent特别之处:1)agent.maxSockets 表示到某个指定的服务器最多的连接数,若有很多请求到同一个服务器那么这个值就需要很大。2)使用Agent默认会打开keepalive 标志,而且这个标志在客户端是没有0超时的,也就是当没有等待的请求时会马上关闭该连接。

6、http.ClientRequest

  使用http.request函数创建的就是http.ClientRequest类,该类表示一个正在执行中的请求。

  http.ClientRequest 实现了Writeable Stream接口,因此可以想其中写入数据。

  重要事件:response 表示当收到服务器的回复时触发,该事件中将有一个http.IncomingMessage参数,通过该参数可以获取具体的回复内容。若没有监听该事件服务器的回复将被丢弃。当监听response时获取的http.IncomingMessage参数,应该在任何可读的时候将数据读出data事件,否则不会触发end事件。

7, http.IncomingMessage  

  http.IncomingMessage 实现了Readable Stream接口,因此可以想其中写入数据.

  http.IncomingMessage 在服务端的request事件中用来读取客户端发送过来的数据,在客户端则在response事件中用于读取从服务端返回的数据。

HTTPS:

  实现了NODE中的HTTPS服务端于客户端,与HTTP类似。

  只是在创建server与request时增加了一些tls的参数。

NET:

  该模块为NODE中的TCP封装。

  net.createServer([options], [connectionListener]) 用于创建一个TCP服务端,可接着调用listen进行监听。其中的属性allowHalfOpen: false 表示是否允许半关闭状态,若为true则收到对方的FIN时不会关闭自己,直到调用了end函数,才发送自身的FIN包
  socket.buffersize 表示node中socket当前的缓冲字符数(非字节数)。随着缓存的增加内存会跟着增加,因此可以与pause、resume配合使用。

  socket.setTimeout(timeout, [callback]) 可以用于设置socket的空闲超时时间
超时无效问题:socket的空闲是指两个方向上都没有数据传输,也就是既没有数据发出去也没有数据进来。
socket.setNoDelay([noDelay]) 用于禁止 Nagle algorithm 算法。   socket.setKeepAlive([enable], [initialDelay]) 用于执行keepalive查询,其中的initialDelay参数表示从最后读写数据到首次发送查询包的间隔时间。   net.isIPv4(input) 提供了判断IP地址有效性的方法。

OS :

  OS模块提供了很多操作系统的信息    

os.endianness()   //返回大端还是小端
os.platform()   ///平台
os.loadavg()     ///返回1、5、15分钟的系统负载情况
os.cpus()     ///返回CPU的情况
os.networkInterfaces()  ///网络接口
os.EOL  ///换行符 

Path:

  提供了一些对目录的处理函数;path.sep path.delimiter 两个属性分别表示目录分隔符与间隔符;

'foo/bar/baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

Process:

  process是一个NODE里面的全局模块,不需要require。在其中提供了对node进程相关信息查询设置处理支持。  

  事件:exit、uncaughtException(表示有未处理的异常,若该事件没有处理则进程默认退出)、信号事件(名称为信号名称,如SIGINT)。

  输入输出:stdout、stderr(这两个当关联到文件或者tty时将是同步类型的流,关联到管道则为异步),stdin(默认时stdin流是处于暂停状态,需要使用resume开启)

  process.argv 表示进程运行时的参数数组。

  process.nextTick(callback) 用于在下一个tick中调用callback,主要用于实现两种功能:暂时让出CPU做其他处理,实现真正的异步回调函数。

(例子来自官方文档)

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
}

maybeSync(true, function() {
  foo();
});
bar();

上述例子当传递给maybeync第一个参数true时则是同步方式调用回调,否则变成异步方式调用回调函数。因此存在不确定性。

正确的方法如下“:
function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);   ///在下一个tick调用回调,就可以保证异步回调
    return;
  }

  fs.stat('file', cb);
}

  process.umask([mask]) 用于设置进程的默认屏蔽字,当进程创建一个文件时将使用到。

Punycode:

  punycode编码为将unicode的url编码成英文以适应dns查询。

  比如:企鹅.com,用Punycode转换后为:xn--hoq754q. com

ReadLine:

  使用该模块可以实现从标准输入中读取数据,以实现交互。

var client = net.createConnection(1337);

var rl = readline.createInterface({
    input : process.stdin,
    output : process.stdout
});

rl.setPrompt('> ');    ///设置提示符
rl.prompt();     ///打印提示符
rl.on('line',function(line){
    if(line === '0') {
        rl.close();    ///关闭
        client.end();
    }else{
        client.write(line);
        rl.prompt();   ///打印提示符
    }
});

QueryString:

  用于处理url中查询参数部分的打包于解析。  

querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
// returns
'foo=bar&baz=qux&baz=quux&corge='

querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
// returns
'foo:bar;baz:qux'

Stream:

  Stream模块应该是node的核心部分了。在0.10中与之前版本的readable有所不同,当没有设置data事件时,若没有调用resume来却换到旧模式将会导致该流一致处于暂停状态。

  Readable抽象类

  new stream.Readable([options]) ,其中的options包括highWaterMark表示最大的缓冲大小

  readable.pipe(destination, [options]) 通过管道将自身数据写入到destination之中。参数end表示readable指定end的时候是否destination也执行end来关闭。 readable.unpipe([destination]) 相反的函数。

  Writable抽象类

  new stream.Writable([options]) 其中的options包括highWaterMark表示最大的缓冲大小

  Duplex抽象类(实现可读可写)

  new stream.Duplex(options) allowHalfOpen参数表示是否允许半关闭状态(TCP)

  Transfer抽象类(是一个Duplex,但是通常输出以某种方式方式关联到输入,如zlib或者加解密)

StringDecode:

  该模块用于将一个buffer解析成一个字符串,类是于Buffer.toString(),但是增加了额外的utf8的支持。

Timer:

  该模块提供了 setTimeout,setInterval 等函数。这些函数都是全局的,直接可以使用。

TLS/SSL:

  实现https的相关支持。

UDP/Datagram:

  实现对UDP数据报的支持。

URL:

  实现对URL的组合于解析功能。

  url.parse(urlStr, [parseQueryString], [slashesDenoteHost]) 将给定的url解析成一个对象。

  url.resolve(from, to)

url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

Util:

  该模块提供了一些基础的函数,如继承。

  util.format(format, [...]) 实现类似于printf的功能  

%s - String.
%d - Number (both integer and float).
%j - JSON.
% - single percent sign ('%'). This does not consume an argument.

  util.inspect(object, [options]) 将object序列化成一个字符串并返回。

util.isArray(object)
util.isRegExp(object)
util.isDate(object)
util.inherits(constructor, superConstructor)  ///设置继承关系,注意执行该操作constructor的prototype将被替换,因此若construtor要修改prototype需要在该函数之后定义。另外可以通过constructor.super_来访问父类。

VM:

  提供了对V8中VM的访问。

ZLib:

  顾名思义了。