Node.js快速入门
来源:互联网 发布:mfc图形界面编程实例 编辑:程序博客网 时间:2024/06/08 16:41
Node.js是什么?
Node.js是建立在谷歌Chrome的JavaScript引擎(V8引擎)的Web应用程序框架。 它的最新版本是:v0.12.7(在编写本教程时的版本)。Node.js在官方网站的定义文件内容如下:
Node.js® is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
Node.js自带运行时环境可在Javascript脚本的基础上可以解释和执行(这类似于JVM的Java字节码)。这个运行时允许在浏览器以外的任何机器上执行JavaScript代码。由于这种运行时在Node.js上,所以JavaScript现在可以在服务器上并执行。
Node.js还提供了各种丰富的JavaScript模块库,它极大简化了使用Node.js来扩展Web应用程序的研究与开发。
Node.js特性
Node.js库的异步和事件驱动的API全部都是异步就是非阻塞。它主要是指基于Node.js的服务器不会等待API返回的数据。服务器移动到下一个API调用,Node.js发生的事件通知机制后有助于服务器获得从之前的API调用的响应。
非常快的内置谷歌Chrome的V8 JavaScript引擎,Node.js库代码执行是非常快的。
单线程但高度可扩展 - Node.js使用具有循环事件单线程模型。事件机制有助于服务器在一个非阻塞的方式响应并使得服务器高度可扩展,而不是创建线程限制来处理请求的传统服务器。Node.js使用单线程的程序,但可以提供比传统的服务器(比如Apache HTTP服务器)的请求服务数量要大得多。
没有缓冲 - Node.js的应用从来不使用缓冲任何数据。这些应用只是输出数据在块中。
许可证协议 - Node.js 在 MIT 协议 下发布
都有谁在使用Node.js?
以下是包含正在使用node.js的项目,应用和公司,一个详尽的清单请点击 github维基链接查看,这些清单里包括:eBay, General Electric, GoDaddy, Microsoft, PayPal, Uber, Wikipins, Yahoo!, Yammer 并越来越多加入继续扩大这个列表:使用NodeJS的项目, 应用和公司
概念
下图描述了 Node.js 的一些重要组成部分,我们将详细的在后续章节进行讨论。
在哪里可以使用Node.js?
以下是Node.js证明自己完美的技术的合作伙伴的领域。
I/O 绑定应用程序
数据流应用
数据密集型实时应用(DIRT)
JSON API的应用程序
单页面应用
在哪些地方不要使用Node.js?
不建议使用Node.js的就是针对CPU密集型应用。
Node.js - 环境安装配置
如果愿意安装设置Node.js环境,需要计算机上提供以下两个软件:
一、文本编辑器
二、Node.js二进制安装包
文本编辑器
这将用来编写程序代码。 一些编辑器包括:Windows记事本,OS Edit命令,Brief, Epsilon, EMACS和VIM或vi。
文本编辑器的名称和版本的在不同的操作系统可能不太相同。例如,记事本可用在Windows,VIM或vi可以在Windows以及Linux或UNIX上使用。
编辑器创建的文件称为源文件并包含程序的源代码。 对于Node.js的程序的源文件名通常命名扩展是 ".js".
在开始编程之前,请确保文本编辑器可用,并且有足够的经验来写计算机程序,将其保存在一个文件,如:helloworld.js,编译并执行。
Node.js 运行时
编写源文件中的源代码只需知道了解JavaScript。Node.js解释器将用于解释和执行JavaScript代码。
Node.js的发行版以二进制安装在SunOS,Linux,Mac OS X和Windows的32位(386)和64位(AMD64)的x86处理器架构操作系统。
以下部分将指导如何将Node.js的二进制分发版安装在各种操作系统上。
下载Node.js的归档文件
下载最新版本Node.js的安装归档文件在: Node.js 下载. 在写这篇教程的时候,下载的是 node-v0.12.7-x64.msi 并复制到“桌面”。
在UNIX/Linux/Mac OS X和SunOS上安装(可选)
解压缩下载归档文件到 /usr/local, 创建一个NodeJs树 /usr/local/nodejs. 例如:
tar -C /usr/local -xzf node-v0.12.0-linux-x86.tar.gz
添加 /usr/local/nodejs 到PATH环境变量。
在Windows上安装Node.js(本教程中使用)
使用MSI文件,并按照提示安装node.js,默认情况下,安装程序将 Node.js 发行到 C:\Program Files\nodejs. 但这里我们需要修改安装路径到:D:\yiibai_worksp\nodejs,并将 D:\yiibai_worksp\nodejs 目录添加到Window系统的PATH环境变量中。重新启动打开命令提示符,以使更改生效。
第一步:双击下载的 “node-v0.12.7-x64.msi" 文件,出现提示安装界面:
第二步:选择安装目录,这里安装在目录 D:\yiibai_worksp\nodejs 中,如下图:
第三步:选择安装的模块和功能,这里全部安装,并添加到系统环境变量,如下图所示:
最后一步:安装完成!
验证安装:执行文件
创建一个js文件名为test.js 在 D:\>yiibai_worksp\nodejs.
File: test.js
console.log("Hello World")
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出结果:
Node.js - 第一个应用程序
在使用 Node.js 创建 Hello World ! 应用程序之前, 让我们看看Node.js的应用程序的组成部分。Node.js应用程序由以下三个重要部分组成:
导入所需模块: 使用require指令来加载javascript模块
创建一个服务器: 服务器这将听监听在Apache HTTP服务器客户端的请求。
读取请求并返回响应: 在前面的步骤中创建的服务器将响应读取由客户机发出的HTTP请求(可以是一个浏览器或控制台)并返回响应。
创建Node.js应用
步骤 1:导入所需的包
使用require指令来加载 HTTP 模块。
var http = require("http")
步骤 2:使用http.createServer方法创建HTTP服务器。通过参数函数请求并响应。编写示例实现返回“Hello World”。服务器在8081端口监听。
http.createServer(function (request, response) { // HTTP Status: 200 : OK // Content Type: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // send the response body as "Hello World" response.end('Hello World\n');}).listen(8081);// console will print the messageconsole.log('Server running at http://127.0.0.1:8081/');
步骤 3: 创建一个 js 文件在 helloworld.js 在 D:\>yiibai_worksp.
File: helloworld.js
var http = require("http")http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n');}).listen(8081);console.log('Server running at http://127.0.0.1:8081/');
现在运行 helloworld.js 看到结果:
D:\yiibai_worksp\nodejs>node helloworld.js
验证输出,服务器应用已经启动!
Server running at http://127.0.0.1:8081/
向Node.js服务器发出请求
打开浏览器(IE),在地址栏中输入:http://127.0.0.1:8081/ 在浏览器中,看看下面的结果。
Node.js - REPL
REPL代表读取评估和演示打印循环,它就像 Window 下的控制台的计算机环境,或 Unix/Linux 系统的 Shell命令输入响应输出。 Node.js或Node 捆绑了一个REPL环境。可执行以下任务。
读取- 读取用户的输入,解析输入的JavaScript数据结构并存储在内存
计算- 采取并评估计算数据结构
打印- 打印结果
循环 - 循环上面的命令,直到用户按Ctrl-C两次终止
Node 的REPL 与 Node.js 的实验代码非常有用,用于调试JavaScript代码。
特点
REPL可以通过简单地在shell/控制台运行node不带任何参数来启动。
D:\yiibai_worksp\nodejs> node
可以看到REPL 命令提示符:
D:\yiibai_worksp\nodejs> node>
简单的表达式
让我们尝试在REPL命令提示符下执行简单的数学运算:
D:\yiibai_worksp\nodejs>node> 1 + 34> 1 + ( 2 * 3 ) - 43>
使用变量
使用变量储存值后并打印。如果不使用var关键字,那么值存储在变量并打印。而如果使用var关键字存储值,那么不会打印。稍后,可以使用这两个变量。使用console.log()打印来任何东西
D:\yiibai_worksp\nodejs> node> x = 1010> var y = 10undefined> x + y20> console.log("Hello World")Hello Workdundefined
多行表达
Node REPL支持类似于JavaScript的多表达。请参阅下列do-while循环:
D:\yiibai_worksp\nodejs> node> var x = 0undefined> do {... x++;... console.log("x: " + x);... } while ( x < 5 );x: 1x: 2x: 3x: 4x: 5undefined>
... 当按下进入自动打开来后括号。Node自动检查表达式的连续性。
下划线变量
使用_得到最后的结果。
D:\yiibai_worksp\nodejs> node> var x = 10undefined> var y = 20undefined> x + y30> var sum = _undefined> console.log(sum)30undefined>
REPL 命令
ctrl + c - 终止当前命令
ctrl + c twice - 终止 Node REPL
ctrl + d - 终止 Node REPL
Up/Down Keys - 查看命令历史记录和修改以前的命令
tab Keys - 当前命令列表
.help - 列出所有命令
.break - 退出多行表达
.clear - 从多行表达式退出
.save - 当前 Node REPL会话保存到一个文件
.load - 加载文件的内容到当前Node REPL会话
D:\yiibai_worksp\nodejs> node> var x = 10undefined> var y = 20undefined> x + y30> var sum = _undefined> console.log(sum)30undefined> .save test.jsSession saved to:test.js> .load test.js> var x = 10undefined> var y = 20undefined> x + y30> var sum = _undefined> console.log(sum)30undefined>
Node.js - npm
npm 表示节点程序包管理器。npm 提供以下两个主要功能:
Node.js包/模块的在线软件仓库,可通过搜索 search.nodejs.org
命令行实用程序安装包,作为Node.js版本管理和依赖包管理。
Node.js v0.6.3版本后才开始捆绑 npm 安装。为了验证,打开控制台,然后输入以下命令并查看结果:
D:\yiibai_worksp\nodejs>npm --version2.11.3
全局VS本地安装
默认情况下,NPM安装在任何依赖性的本地模式。在这里,本地模式指的是包在安装目录node_modules,位于Node应用的文件夹中。本地部署的包都可以通过require() 访问 。
全局安装的软件包/依赖存储在<用户目录>/npm目录。 这种依赖关系可以在命令行中使用Node.js的(命令行界面)任何功能,但不能使用require()在Node直接应用导入。
我们来开始安装明确,使用本地来安装一个流行的Web框架。
D:\yiibai_worksp\nodejs>npm install expressexpress@4.11.2 node_modules\express|-- merge-descriptors@0.0.2|-- utils-merge@1.0.0|-- methods@1.1.1|-- escape-html@1.0.1|-- fresh@0.2.4|-- cookie@0.1.2|-- range-parser@1.0.2|-- media-typer@0.3.0|-- cookie-signature@1.0.5|-- vary@1.0.0|-- finalhandler@0.3.3|-- parseurl@1.3.0|-- serve-static@1.8.1|-- content-disposition@0.5.0|-- path-to-regexp@0.1.3|-- depd@1.0.0|-- qs@2.3.3|-- debug@2.1.1 (ms@0.6.2)|-- send@0.11.1 (destroy@1.0.3, ms@0.7.0, mime@1.2.11)|-- on-finished@2.2.0 (ee-first@1.1.0)|-- type-is@1.5.7 (mime-types@2.0.9)|-- accepts@1.2.3 (negotiator@0.5.0, mime-types@2.0.9)|-- etag@1.5.1 (crc@3.2.1)|-- proxy-addr@1.0.6 (forwarded@0.1.0, ipaddr.js@0.1.8)
一旦NPM完成下载,可以通过查看 D:\yiibai_worksp\nodejs\node_modules 的内容验证,或键入以下命令:
D:\yiibai_worksp\nodejs> npm lsD:\yiibai_worksp\nodejs|-- express@4.11.2 |-- accepts@1.2.3 | |-- mime-types@2.0.9 | | |-- mime-db@1.7.0 | |-- negotiator@0.5.0 |-- content-disposition@0.5.0 |-- cookie@0.1.2 |-- cookie-signature@1.0.5 |-- debug@2.1.1 | |-- ms@0.6.2 |-- depd@1.0.0 |-- escape-html@1.0.1 |-- etag@1.5.1 | |-- crc@3.2.1 |-- finalhandler@0.3.3 |-- fresh@0.2.4 |-- media-typer@0.3.0 |-- merge-descriptors@0.0.2 |-- methods@1.1.1 |-- on-finished@2.2.0 | |-- ee-first@1.1.0 |-- parseurl@1.3.0 |-- path-to-regexp@0.1.3 |-- proxy-addr@1.0.6 | |-- forwarded@0.1.0 | |-- ipaddr.js@0.1.8 |-- qs@2.3.3 |-- range-parser@1.0.2 |-- send@0.11.1 | |-- destroy@1.0.3 | |-- mime@1.2.11 | |-- ms@0.7.0 |-- serve-static@1.8.1 |-- type-is@1.5.7 | |-- mime-types@2.0.9 | |-- mime-db@1.7.0 |-- utils-merge@1.0.0 |-- vary@1.0.0
上面列出的内容很长,这里省略了一部分。
现在,让我们尝试安装明确,使用全局安装流行Web框架。
D:\yiibai_worksp\nodjs> npm install express - g
一旦NPM完成下载,可以通过查看<用户目录>/nmp/node_modules中的内容来验证。或输入以下命令:
D:\yiibai_worksp\nodejs> npm ls -g
以上可能会遇网络问题无法安装,需要翻墙。
安装模块
安装模块很简单,只要键入以下命令。
D:\yiibai_worksp\nodejs> npm install express
现在,可以在 js 文件中使用它,如下:
var express = require('express');
package.json 包
package.json是存在于任何Node应用程序/模块的根目录,并用于定义一个包的属性。 让我们打开 package.json express包在 D:\yiibai_worksp\nodejs\node_modules\express\
{ "name": "express", "description": "Fast, unopinionated, minimalist web framework", "version": "4.11.2", "author": { "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" }, "contributors": [ { "name": "Aaron Heckmann", "email": "aaron.heckmann+github@gmail.com" }, { "name": "Ciaran Jessup", "email": "ciaranj@gmail.com" }, { "name": "Douglas Christopher Wilson", "email": "doug@somethingdoug.com" }, { "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }, { "name": "Jonathan Ong", "email": "me@jongleberry.com" }, { "name": "Roman Shtylman", "email": "shtylman+expressjs@gmail.com" }, { "name": "Young Jae Sim", "email": "hanul@hanul.me" } ], "license": "MIT", "repository": { "type": "git", "url": "https://github.com/strongloop/express" }, "homepage": "http://expressjs.com/", "keywords": [ "express", "framework", "sinatra", "web", "rest", "restful", "router", "app", "api" ], "dependencies": { "accepts": "~1.2.3", "content-disposition": "0.5.0", "cookie-signature": "1.0.5", "debug": "~2.1.1", "depd": "~1.0.0", "escape-html": "1.0.1", "etag": "~1.5.1", "finalhandler": "0.3.3", "fresh": "0.2.4", "media-typer": "0.3.0", "methods": "~1.1.1", "on-finished": "~2.2.0", "parseurl": "~1.3.0", "path-to-regexp": "0.1.3", "proxy-addr": "~1.0.6", "qs": "2.3.3", "range-parser": "~1.0.2", "send": "0.11.1", "serve-static": "~1.8.1", "type-is": "~1.5.6", "vary": "~1.0.0", "cookie": "0.1.2", "merge-descriptors": "0.0.2", "utils-merge": "1.0.0" }, "devDependencies": { "after": "0.8.1", "ejs": "2.1.4", "istanbul": "0.3.5", "marked": "0.3.3", "mocha": "~2.1.0", "should": "~4.6.2", "supertest": "~0.15.0", "hjs": "~0.0.6", "body-parser": "~1.11.0", "connect-redis": "~2.2.0", "cookie-parser": "~1.3.3", "express-session": "~1.10.2", "jade": "~1.9.1", "method-override": "~2.3.1", "morgan": "~1.5.1", "multiparty": "~4.1.1", "vhost": "~3.0.0" }, "engines": { "node": ">= 0.10.0" }, "files": [ "LICENSE", "History.md", "Readme.md", "index.js", "lib/" ], "scripts": { "test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/", "test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/ test/acceptance/" }, "gitHead": "63ab25579bda70b4927a179b580a9c580b6c7ada", "bugs": { "url": "https://github.com/strongloop/express/issues" }, "_id": "express@4.11.2", "_shasum": "8df3d5a9ac848585f00a0777601823faecd3b148", "_from": "express@*", "_npmVersion": "1.4.28", "_npmUser": { "name": "dougwilson", "email": "doug@somethingdoug.com" }, "maintainers": [ { "name": "tjholowaychuk", "email": "tj@vision-media.ca" }, { "name": "jongleberry", "email": "jonathanrichardong@gmail.com" }, { "name": "shtylman", "email": "shtylman@gmail.com" }, { "name": "dougwilson", "email": "doug@somethingdoug.com" }, { "name": "aredridel", "email": "aredridel@nbtsc.org" }, { "name": "strongloop", "email": "callback@strongloop.com" }, { "name": "rfeng", "email": "enjoyjava@gmail.com" } ], "dist": { "shasum": "8df3d5a9ac848585f00a0777601823faecd3b148", "tarball": "http://registry.npmjs.org/express/-/express-4.11.2.tgz" }, "directories": {}, "_resolved": "https://registry.npmjs.org/express/-/express-4.11.2.tgz", "readme": "ERROR: No README data found!"}
Package.json 属性
name - 包的名称
version - 包的版本
description - 包的描述
homepage - 包的网站主页
author - 包的作者
contributors - 包的贡献者的名称列表
dependencies - 依赖性列表。npm自动安装所有在node_module文件夹中的包提到的依赖关系。
repository - 包的存储库类型和URL
main - 包的入口点
keywords - 关键字
卸载模块
请使用以下命令卸载模块。
D:\yiibai_worksp\nodejs> npm uninstall express
当npm卸载的软件包,可以通过查看<用户目录>/npm/node_modules 的内容验证。或键入以下命令:
D:\yiibai_worksp\nodejs> npm ls
更新模块
更新的package.json并更改其版本依赖关系进行更新,运行以下命令。
D:\yiibai_worksp\nodejs> npm update
搜索模块
使用npm搜索包名。
D:\yiibai_worksp\nodejs>npm search express
创建一个模块
创建模块需要要生成package.json。让我们使用 npm 产生 package.json。
D:\yiibai_worksp\nodejs> npm initThis utility will walk you through creating a package.json file.It only covers the most common items, and tries to guess sane defaults.See 'npm help json' for definitive documentation on these fieldsand exactly what they do.Use 'npm install <pkg> --save' afterwards to install a package andsave it as a dependency in the package.json file.Press ^C at any time to quit.name: (Nodejs_WorkSpace)
一旦的 package.json 产生。使用一个有效的电子邮件地址在npm库网站上注册自己,使用如面的命令。
D:\yiibai_worksp\nodejs> npm adduser
现在,是时候来发布模块了:
D:\yiibai_worksp\nodejs> npm publish
Node.js - 回调概念
什么是回调?
回调是一种异步相当于一个函数。回调函数被调用在完成既定任务。Node大量使用了回调。Node所有的API写的都是支持回调的这样一种方式。例如,一个函数读取一个文件可能开始读取文件,并立即返回控制到执行环境 使得下一个指令可以马上被执行。一旦文件 I/O 完成,它会调用回调函数,同时传递回调函数,该文件作为参数的内容。因此不会有堵塞或等待文件I/O。这使得Node.js高度可扩展,因此可以处理大量的请求,而无需等待任何函数来返回结果。
阻塞代码示例
创建一个 txt 文件:test.txt 在 D:\>yiibai_worksp\nodejs 目录
Yiibai.Com
创建一个名为test.js 的js文件在 D:\>yiibai_worksp\nodejs
var fs = require("fs");var data = fs.readFileSync('test.txt');console.log(data.toString());console.log("Program Ended");
现在运行 test.js 看到的结果:
D:\yiibai_worksp\nodejs>node test.js
验证输出结果:
Yiibai.comProgram Ended
非阻塞代码示例
创建一个 txt 文件:test.txt 在 D:\>yiibai_worksp\nodejs 目录
Yiibai.Com
更新 test.js 的内容在目录D:\>yiibai_worksp\nodejs
var fs = require("fs");fs.readFile('test.txt', function (err, data) { if (err) return console.error(err); console.log(data.toString());});console.log("Program Ended");
现在运行 test.js 看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出
Program EndedYiibai.Com
事件循环概述
Node JS是单线程应用程序,但它通过事件和回调的概念,支持并发。NodeJS的每一个API都是异步的,作为一个单独的线程,它使用异步函数调用来维护并发。Node使用观察者模式。Node线程保持一个事件循环,每当任何任务完成后得到结果,它触发通知事件侦听函数来执行相应的事件。
事件驱动编程
Node.js使用大量事件,这也是为什么Node.js相对于其他类似技术比较快的原因之一。当Node启动其服务器,就可以简单地初始化其变量,声明函数,然后等待事件的发生。
虽然事件似乎类似于回调。不同之处在于当回调函数被调用异步函数返回结果,其中的事件处理工作在观察者模式。监听事件函数作为观察者。每当一个事件被解雇,其监听函数开始执行。Node.js有多个内置的事件。 主要扮演者是 EventEmitter,可使用以下语法导入。
//import events modulevar events = require('events');//create an eventEmitter objectvar eventEmitter = new events.EventEmitter();
示例
创建一个 js 文件名为 test.js 的文件在D:\>yiibai_worksp\nodejs
File: test.js
//import events modulevar events = require('events');//create an eventEmitter objectvar eventEmitter = new events.EventEmitter();//create a function connected which is to be executed //when 'connection' event occursvar connected = function connected() { console.log('connection succesful.'); // fire the data_received event eventEmitter.emit('data_received.');}// bind the connection event with the connected functioneventEmitter.on('connection', connected); // bind the data_received event with the anonymous functioneventEmitter.on('data_received', function(){ console.log('data received succesfully.');});// fire the connection event eventEmitter.emit('connection');console.log("Program Ended.");
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出。服务器已经启动
connection succesful.data received succesfully.Program Ended.
Node应用程序如何工作?
在Node 应用,任何异步函数接受回调作为最后的参数,并回调函数接受错误作为第一个参数。我们再看一下前面的例子。
var fs = require("fs");fs.readFile('test.txt', function (err, data) { if (err){ console.log(err.stack); return;} console.log(data.toString());});console.log("Program Ended");
这里fs.readFile是一个异步函数,其目的是用于读取文件。 如果在文件的读取发生了错误,则err 对象将包含相应的错误,否则data将包含该文件的内容。readFile通过err和data到回调函数后,文件读取操作完成。
Node.js - 事件发射器
EventEmitter类在于事件的模块。它通过通俗易懂的语法如下:
//import events modulevar events = require('events');//create an eventEmitter objectvar eventEmitter = new events.EventEmitter();
当EventEmitter实例出现任何错误,它会发出“error”事件。当新的监听器添加,'newListener'事件被触发,当一个监听器被删除,'removeListener“事件被触发。
EventEmitter提供多种属性,如:on和emit。on属性用于绑定与该事件的函数,而 emit 用于触发一个事件。
方法
类方法
事件
event - 字符串 - 事件名称
listener- 函数-事件处理函数
event - 字符串事件名称
listener- 函数的事件处理函数
示例
创建一个js文件名为test.js,在 D:\>yiibai_worksp\nodejs
File: test.js
var events = require('events');var eventEmitter = new events.EventEmitter();//listener #1var listner1 = function listner1() { console.log('listner1 executed.');}//listener #2var listner2 = function listner2() { console.log('listner2 executed.');}// bind the connection event with the listner1 functioneventEmitter.addListener('connection', listner1);// bind the connection event with the listner2 functioneventEmitter.on('connection', listner2);var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');console.log(eventListeners + " Listner(s) listening to connection event");// fire the connection event eventEmitter.emit('connection');// remove the binding of listner1 functioneventEmitter.removeListener('connection', listner1);console.log("Listner1 will not listen now.");// fire the connection event eventEmitter.emit('connection');eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');console.log(eventListeners + " Listner(s) listening to connection event");console.log("Program Ended.");
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出。服务器已经启动
2 Listner(s) listening to connection eventlistner1 executed.listner2 executed.Listner1 will not listen now.listner2 executed.1 Listner(s) listening to connection eventProgram Ended.
Node.js - 缓冲模块
缓冲器模块可以被用来创建缓冲区和SlowBuffer类。缓冲模块可以使用以下语法导入。var buffer = require("buffer")
Buffer 类
Buffer类是一个全局类,可以在应用程序,无需导入缓冲模块进行访问。缓冲区是一种整数数组并对应于原始存储器V8堆以外分配。 缓冲区不能调整大小。
类方法
编码字符串 - 编码字符串测试
obj Object
Return: Boolean
string字符串
编码字符串,可选,默认: 'utf8'
Return: Number
缓冲区列表数组列表对象到Concat
当串联后缓冲区的数目是totalLength总长度
buf1 Buffer
buf2 Buffer
示例
创建一个js文件名为test.js,在 D:\>yiibai_worksp\nodejs
File: test.js
//create a buffervar buffer = new Buffer(26);console.log("buffer length: " + buffer.length);//write to buffervar data = "YiiBai.com";buffer.write(data);console.log(data + ": " + data.length + " characters, " + Buffer.byteLength(data, 'utf8') + " bytes");//slicing a buffervar buffer1 = buffer.slice(0,14);console.log("buffer1 length: " + buffer1.length);console.log("buffer1 content: " + buffer1.toString());//modify buffer by indexesfor (var i = 0 ; i < 26 ; i++) { buffer[i] = i + 97; // 97 is ASCII a}console.log("buffer content: " + buffer.toString('ascii'));var buffer2 = new Buffer(4);buffer2[0] = 0x3;buffer2[1] = 0x4;buffer2[2] = 0x23;buffer2[3] = 0x42;//reading from bufferconsole.log(buffer2.readUInt16BE(0));console.log(buffer2.readUInt16LE(0));console.log(buffer2.readUInt16BE(1));console.log(buffer2.readUInt16LE(1));console.log(buffer2.readUInt16BE(2));console.log(buffer2.readUInt16LE(2));var buffer3 = new Buffer(4);buffer3.writeUInt16BE(0xdead, 0);buffer3.writeUInt16BE(0xbeef, 2);console.log(buffer3);buffer3.writeUInt16LE(0xdead, 0);buffer3.writeUInt16LE(0xbeef, 2);console.log(buffer3);//convert to a JSON Objectvar json = buffer3.toJSON();console.log("JSON Representation : ");console.log(json);//Get a buffer from JSON Objectvar buffer6 = new Buffer(json);console.log(buffer6);//copy a buffervar buffer4 = new Buffer(26);buffer.copy(buffer4);console.log("buffer4 content: " + buffer4.toString());//concatenate a buffervar buffer5 = Buffer.concat([buffer,buffer4]);console.log("buffer5 content: " + buffer5.toString());
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出结果
buffer length: 26YiiBai.com: 18 characters, 18 bytesbuffer1 length: 14buffer1 content: YiiBaibuffer content: abcdefghijklmnopqrstuvwxyz772102710598964902616931<Buffer de ad be ef><Buffer ad de ef be>buffer4 content: abcdefghijklmnopqrstuvwxyzbuffer5 content: abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
Node.js - 数据流
什么是数据流?
数据流是从源数据读取或写入数据到目标对象以。在节点中,有四种类型的流:
Readable - 数据流,其是用于读操作
Writable - 数据流,用在写操作
Duplex - 数据流,其可以用于读取和写入操作
Transform - 双相类型流,输出基于输入进行计算
每种类型的流是EventEmitter,并且一次引发几个事件。例如,一些常用的事件是:
data - 当有数据可读取时触发此事件
end - 当没有更多的数据读取时触发此事件
error - 当有错误或接收数据写入时触发此事件
finish - 当所有数据已刷新到底层系统时触发此事件
从数据流中读取
创建一个txt文件名为test.txt,在 D:\>yiibai_worksp\nodejs
Yiibai.Com
创建一个文件 test.js 在目录 D:\>yiibai_worksp\nodejs
var fs = require("fs");var data = '';//create a readable streamvar readerStream = fs.createReadStream('test.txt');//set the encoding to be utf8. readerStream.setEncoding('UTF8');//handle stream eventsreaderStream.on('data', function(chunk) { data += chunk;});readerStream.on('end',function(){ console.log(data);});readerStream.on('error', function(err){ console.log(err.stack);});console.log("Program Ended");
现在运行 test.js 看到的结果如下:
D:\yiibai_worksp\nodejs> node test.js
验证输出结果:
Program EndedYiibai.Com
写入到流
更新文件 test.js 内容在目录 D:\>yiibai_worksp\nodejs
var fs = require("fs");var data = 'Yiibai.Com';//create a writable streamvar writerStream = fs.createWriteStream('test1.txt');//write the data to stream//set the encoding to be utf8. writerStream.write(data,'UTF8');//mark the end of filewriterStream.end();//handle stream eventswriterStream.on('finish', function() { console.log("Write completed.");});writerStream.on('error', function(err){ console.log(err.stack);});console.log("Program Ended");
现在运行 test.js 看到的结果:
D:\yiibai_worksp\nodejs>node test.js
验证输出:
Program EndedWrite completed.
打开文件 test1.txt 在目录 D:\>yiibai_worksp\nodejs. 验证输出结果:
Yiibai.Com
管道流
管道是一种机制,一个流的输出连接到另一个流(作为另外一个流的输入)。它通常用来从一个流中获取数据,并通过该流输出到另一个流。管道没有对操作限制。考虑上面的例子中,在这里我们使用readerStream 读取test.txt的内容,并使用 writerStream 写入 test1.txt。现在,我们将用管道来简化操作,或者从一个文件中读取并写入到另一个文件。
更新 test.js 文件的内容,在目录 D:\>yiibai_worksp\nodejs, 如下:var fs = require("fs");//create a readable streamvar readerStream = fs.createReadStream('test.txt');//create a writable streamvar writerStream = fs.createWriteStream('test2.txt');//pipe the read and write operations//read test.txt and write data to test2.txtreaderStream.pipe(writerStream);console.log("Program Ended");
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出的结果:
Program Ended
打开文件 test2.txt 在 D:\>yiibai_worksp\nodejs. 验证输出结果:
Yiibai.Com
Node.js - 文件系统
fs模块用于文件I/O。 fs模块可以使用以下语法导入。var fs = require("fs")
同步 vs 异步
每一个fs模块的方法都有同步和异步形式。异步方法接受一个最后的参数为完成回调函数,而回调函数的第一个参数是错误。它优选使用异步方法来代替同步方法,前者从未阻塞程序执行,而后者则会阻塞。
示例
创建一个js文件名为test.js 在目录 D:\>yiibai_worksp\nodejs
File: test.js
var fs = require("fs");//Asynchronous readfs.readFile('test.txt', function (err, data) { if (err) return console.error(err); console.log("Asynchronous read: " + data.toString());});//Synchronous readvar data = fs.readFileSync('test.txt');console.log("Synchronous read: " + data.toString());console.log("Program Ended");
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出结果:
Synchronous read: Yiibai.ComProgram EndedAsynchronous read: Yiibai.Com
方法
标志
标志进行读/写操作是:
r - 打开文件进行读取。如果该文件不存在发生异常。
r+ - 打开文件进行读取和写入。如果该文件不存在发生异常。
rs - 打开文件,用于读取在同步方式。指示操作系统绕过本地文件系统高速缓存。这是对NFS挂载打开文件,因为它可以让你跳过潜在陈旧的本地缓存中很有用。它对I/O性能有非常现实的影响,除非需要它,否则不要使用此标志。注意,这无法打开 fs.open() 到一个同步阻塞调用。如果这不是真想要的,那么应该使用fs.openSync()。
rs+ - 打开文件进行读取和写入,告诉操作系统同步地打开它。 对于'rs'有关异步使用 - 要慎用。
w - 打开文件进行写入。该文件被创建(如果它不存在)或截断清空内容(如果存在)。
wx - 类似“w”,但如果路径存在,则失败。
w+ - 打开文件进行读取和写入。该文件被创建(如果它不存在)或截断清空内容(如果存在)。
wx+ - 类似 “w+”,但如果路径存在,则失败
a - 打开文件进行追加。如果文件不存在,则创建该文件
ax - 类似“a”,但如果路径存在则失败
a+ - 打开文件进行读取和追加内容。如果文件不存在,则创建该文件
ax+' - 类似 'a+',但如果路径存在则会失败
示例
Yiibai.Com
创建一个js文件名为test.js 在D:\>yiibai_worksp\nodejs 目录中。
File: test.js
var fs = require("fs");var buffer = new Buffer(1024);//Example: Opening Filefunction openFile(){ console.log("\nOpen file"); fs.open('test.txt', 'r+', function(err,fd) { if (err) console.log(err.stack); console.log("File opened"); });}//Example: Getting File Infofunction getStats(){ console.log("\nGetting File Info"); fs.stat('test.txt', function (err, stats) { if (err) console.log(err.stack); console.log(stats); console.log("isFile ? "+stats.isFile()); console.log("isDirectory ? "+stats.isDirectory()); });}//Example: Writing Filefunction writeFile(){ console.log("\nWrite file"); fs.open('test1.txt', 'w+', function(err,fd) { var data = "Yiibai.com - Simply Easy Learning!"; buffer.write(data); fs.write(fd, buffer,0,data.length,0,function(err, bytes){ if (err) console.log(err.stack); console.log(bytes + " written!"); }); });}//Example: Read Filefunction readFile(){ console.log("\nRead file"); fs.open('test1.txt', 'r+', function(err,fd) { if (err) console.log(err.stack); fs.read(fd, buffer,0,buffer.length,0,function(err, bytes){ if (err) console.log(err.stack); console.log(bytes + " read!"); if(bytes > 0){ console.log(buffer.slice(0,bytes).toString()); } }); });}function closeFile(){ console.log("\nClose file"); fs.open('test.txt', 'r+', function(err,fd) { if (err) console.log(err.stack); fs.close(fd,function(){ if (err) console.log(err.stack); console.log("File closed!"); }); });}function deleteFile(){ console.log("\nDelete file"); fs.open('test1.txt', 'r+', function(err,fd) { fs.unlink('test1.txt', function(err) { if (err) console.log(err.stack); console.log("File deleted!"); }); });}function truncateFile(){ console.log("\nTruncate file"); fs.open('test.txt', 'r+', function(err,fd) { fs.ftruncate(fd, function(err) { if (err) console.log(err.stack); console.log("File truncated!"); }); });}function createDirectory(){console.log("\nCreate Directory");fs.mkdir('test',function(err){ if(!err){ console.log("Directory created!"); } if(err && err.code === 'EEXIST'){ console.log("Directory exists!"); } else if (err) { console.log(err.stack); }});}function removeDirectory(){console.log("\nRemove Directory");fs.rmdir('test',function(err){ if(!err){ console.log("Directory removed!"); } if (err) { console.log("Directory do not exist!"); }});}function watchFile(){ fs.watch('test.txt', function (event, filename) { console.log('event is: ' + event); });}//Opening fileopenFile();//Writing FilewriteFile();//Reading File readFile();//Closing FilescloseFile();//Getting file informationgetStats(); //Deleting FilesdeleteFile(); //Truncating FilestruncateFile(); //Creating DirectoriescreateDirectory();//Removing DirectoriesremoveDirectory(); //Watching File ChangeswatchFile();
现在运行 test.js 看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出:
Open fileWrite fileRead fileClose fileGetting File InfoDelete fileTruncate fileCreate DirectoryRemove DirectoryFile opened{ dev: 0, mode: 33206, nlink: 1, uid: 0, gid: 0, rdev: 0, ino: 0, size: 0, atime: Fri Jan 01 2010 00:02:15 GMT+0530 (India Standard Time), mtime: Sun Feb 15 2015 13:33:09 GMT+0530 (India Standard Time), ctime: Fri Jan 01 2010 00:02:15 GMT+0530 (India Standard Time) }isFile ? trueisDirectory ? falseDirectory created!Directory removed!event is: renameevent is: rename42 written!42 read!Yiibai.com - Simply Easy Learning!File closed!File deleted!File truncated!event is: change
Node.js - 工具模块
在这篇文章中,我们将讨论一些Node.js库提供的工具模块,这是非常常见的,经常使用在整个应用程序中。
用于打印输出和错误信息2Process
用于获取当前进程的信息,提供处理相关活动的多个事件3OS Module
提供基本的操作系统相关的实用功能4Path Module
实用工具提供用于处理和转化文件路径5Net Module
提供服务器和客户端的数据流。作为一个网络应用包6DNS Module
提供的功能做实际的DNS查找,以及使用底层操作系统的名称解析功能7Domain Module
提供一种方式来处理多个不同的I/O操作为一个组
Node.js - 控制台
方法
示例
创建一个js文件名为test.js 在目录 D:\>yiibai_worksp\nodejs
File: test.js
var counter = 10;console.log("Counter: %d", counter);console.time("Getting data");//make a database call to retrive the data//getDataFromDataBase();console.timeEnd('Getting data');console.info("Program Ended!")
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出
Counter: 10Getting data: 0msProgram Ended!
Node.js - 进程
process 是一个全局性对象,并用于表示Node进程。
退出码
节点正常退出时带状态0码,在没有更多的异步操作挂起时。其他退出代码描述如下:
事件
Process(进程)是一个eventEmitter,并且它发出下列事件
属性
Process(进程)提供了许多有用的特性,以更好地控制系统的相互作用。
方法
Process(进程)提供了许多有用的方法,以更好的控制系统的相互作用。
示例
创建一个js文件名为test.js 在目录 D:\>yiibai_worksp\nodejs
File: test.js
var util = require('util');//printing to consoleprocess.stdout.write("Hello World!" + "\n");//reading passed parameterprocess.argv.forEach(function(val, index, array) { console.log(index + ': ' + val);});//executable pathconsole.log(process.execPath);//print the current directoryconsole.log('Current directory: ' + process.cwd());//print the process versionconsole.log('Current version: ' + process.version);//print the memory usageconsole.log(util.inspect(process.memoryUsage()));
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出:
Hello World!0: node1: D:\yiibai_worksp\nodejs\test.jsD:\yiibai_worksp\nodejs\node.exeCurrent directory: D:\yiibai_worksp\nodejsCurrent version: v0.12.7{ rss: 16379904, heapTotal: 9751808, heapUsed: 4067896 }
Node.js - OS 模块
os模块用于一些基本的操作系统相关的实用功能。os模块可以使用以下语法导入。
var os = require("os")
方法
属性
示例
创建一个js文件名为test.js 在 D:\>yiibai_worksp\nodejs
File: test.js
var os = require("os");//endiannessconsole.log('endianness : ' + os.endianness());//typeconsole.log('type : ' + os.type());//platformconsole.log('platform : ' + os.platform());//totalmemconsole.log('total memory : ' + os.totalmem() + " bytes.");//freememconsole.log('free memory : ' + os.freemem() + " bytes.");
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出:
endianness : LEtype : Windows_NTplatform : win32total memory : 4201889792 bytes.free memory : 1233211392 bytes.
Node.js - Path 模块
path 模块用于处理和转换文件路径。path模块可以使用以下语法导入。
var path = require("path")
属性
进程提供了许多有用的特性,以获得更好的控制系统的相互作用。
方法
示例
创建一个js文件名为test.js 在 D:\>yiibai_worksp\nodejs
File: test.js
var path = require("path");//normalizationconsole.log('normalization : ' + path.normalize('/test/test1//2slashes/1slash/tab/..'));//joinconsole.log('joint path : ' + path.join('/test', 'test1', '2slashes/1slash', 'tab', '..'));//resolveconsole.log('resolve : ' + path.resolve('test.js'));//extNameconsole.log('ext name : ' + path.extname('test.js'));
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出:
normalization : \test\test1\2slashes\1slashjoint path : \test\test1\2slashes\1slashresolve : D:\yiibai_worksp\nodejs\test.jsext name : .js
Node.js - Net模块
net 模块是用来创建服务器和客户端。它提供了一个异步网络包装。 net模块可以使用以下语法导入。
var net = require("net")
方法
Class:net.Server
此类用于创建TCP或本地服务器。
方法
事件
Class:net.Socket
这个对象是一个TCP或本地套接字的抽象。net.Socket的实例实现全双工流接口。它们可以由用户创建,并用作一个客户端(使用connect()),也可以由Node创建并通过服务器的'连接'事件传递给用户。
事件
net.Socket是一个eventEmitter,它发出下列事件。
属性
net.Socket提供了许多有用的特性,以更好的控制套接字的相互作用。
方法
示例
创建一个js文件名为server.js 在 D:\>yiibai_worksp\nodejs
File: server.js
var net = require('net');var server = net.createServer(function(connection) { console.log('client connected'); connection.on('end', function() { console.log('client disconnected'); }); connection.write('Welcome to Yiibai Yiibai!\r\n'); connection.pipe(connection);});server.listen(8080, function() { console.log('server is listening');});
现在运行server.js看到的结果:
D:\yiibai_worksp\nodejs>node server.js
验证输出。
server is listening
创建一个js文件名为client.js 在 C:\>Nodejs_WorkSpace.
File: client.js
var net = require('net');var client = net.connect({port: 8080}, function() { console.log('connected to server!'); });client.on('data', function(data) { console.log(data.toString()); client.end();});client.on('end', function() { console.log('disconnected from server');});
现在启动另一个命令行窗口,运行 client.js 看到结果:
D:\yiibai_worksp\nodejs>node client.js
验证输出:
connected to server!Welcome to Yiibai Yiibai!disconnected from server
验证,其中server.js运行输出在终端上如下:
server is listeningclient connectedclient disconnected
Node.js - DNS 模块
dns 模块是用来做实际的DNS查找,以及使用底层操作系统的名称解析功能..它提供了一个异步网络包装。dns模块可以使用以下语法导入。
var dns = require("dns")
方法
rrtypes
以下是所使用dns.resolve()方法的有效rrtypes的列表
A - IPV4 地址(默认)
AAAA - IPV6 地址
MX - 邮件交换记录
TXT - 文字记录
SRV - SRV记录
PTR - 用于逆向IP查找
NS - 域名服务器记录
CNAME - 规范名称记录
SOA - 规范记录的开始
错误代码
每个DNS查询可以返回下列错误代码之一:
dns.NODATA - DNS服务器返回回答不含数据
dns.FORMERR - DNS服务器要求查询是misformatted
dns.SERVFAIL - DNS服务器返回的一般故障
dns.NOTFOUND - 域名未找到
dns.NOTIMP - DNS服务器不执行请求操作
dns.REFUSED - DNS服务器拒绝查询
dns.BADQUERY - 非格式化的DNS查询
dns.BADNAME - 非格式化的主机名
dns.BADFAMILY - 不支持的地址族
dns.BADRESP - Misformatted DNS回复
dns.CONNREFUSED - 无法联系DNS服务器
dns.TIMEOUT - 超时在联系DNS服务器的时候
dns.EOF - 文件的结尾
dns.FILE - 读取文件错误
dns.NOMEM - 内存不足
dns.DESTRUCTION - 信道被销毁
dns.BADSTR - 非法格式化字符串
dns.BADFLAGS - 非法标志指定
dns.NONAME - 给定主机名不是数字
dns.BADHINTS - 非法提示标志指定
dns.NOTINITIALIZED - c-ares库初始化尚未执行
dns.LOADIPHLPAPI - 加载 iphlpapi.dll 错误
dns.ADDRGETNETWORKPARAMS - 找不到GetNetworkParams函数
dns.CANCELLED - DNS查询取消
示例
创建一个js文件名为test.js 在 D:\>yiibai_worksp\nodejs
File: test.js
var dns = require('dns');dns.lookup('www.yiibai.com', function onLookup(err, address, family) { console.log('address:', address); dns.reverse(address, function (err, hostnames) { if (err) { console.log(err.stack); } console.log('reverse for ' + address + ': ' + JSON.stringify(hostnames));}); });
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs> node test.js
验证输出:
address: 112.124.103.85Error: getHostByAddr ENOTFOUND 112.124.103.85 at errnoException (dns.js:44:10) at Object.onresolve [as oncomplete] (dns.js:199:19)reverse for 112.124.103.85: undefined
Node.js - Domain模块
domain 模块是用于拦截未处理的错误。这些未处理的错误可以使用内部绑定或外部绑定来拦截。如果错误都那么不处理,那么Node应用会崩溃。
内部绑定 - 错误发生执行代码是在一个域的run方法。
外部绑定 - 使用它的add方法将错误发生明确地加入到域。
domain(域)模块可以使用以下语法导入。
var domain = require("domain")
域模块的Domain类是用来提供路由错误以及未捕获异常活动域对象的功能。 这是一个EventEmitter的子类。为了处理它捕获错误,监听它的错误事件。它使用如下的语法创建:
var domain = require("domain");var domain1 = domain.create();
方法
属性
示例
创建一个js文件名为test.js 在 D:\>yiibai_worksp\nodejs
File: test.js
var EventEmitter = require("events").EventEmitter;var domain = require("domain");var emitter1 = new EventEmitter();//Create a domainvar domain1 = domain.create();domain1.on('error', function(err){ console.log("domain1 handled this error ("+err.message+")");});//explicit binding domain1.add(emitter1);emitter1.on('error',function(err){ console.log("listener handled this error ("+err.message+")");});emitter1.emit('error',new Error('To be handled by listener'));emitter1.removeAllListeners('error');emitter1.emit('error',new Error('To be handled by domain1'));var domain2 = domain.create();domain2.on('error', function(err){ console.log("domain2 handled this error ("+err.message+")");});//implicit bindingdomain2.run(function(){ var emitter2 = new EventEmitter(); emitter2.emit('error',new Error('To be handled by domain2')); });domain1.remove(emitter1);emitter1.emit('error',new Error('Converted to exception. System will crash!'));
现在运行test.js看到的结果:
D:\yiibai_worksp\nodejs>node test.js
验证输出:
listener handled this error (To be handled by listener)domain1 handled this error (To be handled by domain1)domain2 handled this error (To be handled by domain2)events.js:72 throw er; // Unhandled 'error' event ^Error: Converted to exception. System will crash! at Object.<anonymous> (C:\Nodejs_WorkSpace\test.js:42:23) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:929:3
Node.js - Web模块
Web服务器简介
Web服务器是用于处理使用HTTP协议请求并返回网页作为响应到客户端的软件应用程序。 Web服务器通常提供HTML文档并伴随着图片,样式表和脚本。大多数Web服务器还支持使用脚本语言作为服务器端脚本,或重定向到从数据库中获取数据的执行特定任务的应用程序服务器,执行复杂的逻辑等,Web服务器然后返回应用服务器到客户端输出。
Apache web服务器是最常见的一个网络服务器。它是一个开源项目。
路径定位过程
Web服务器映射使用URL,统一资源定位符的文件的路径。它可以是一个本地文件系统或一个外部/内部程序。例如:
客户端使用的浏览器发起一个URL请求:http://www.test-example-site.com/website/index.htm.
浏览器发起的一个请求是:
Web服务器将追加路径到根目录。举个例子:根目录是home/www,那么实际路径将被转换为 home/www/website/index.htm.
Web网络架构介绍
Web应用程序的使用分为四层:
Client - 此层是由Web浏览器,移动浏览器或应用程序,它可以发起HTTP请求到服务器。
Server - 这一层包括可拦截发出的客户端请求,并将其传递到由Web服务器响应。
Business - 这一层由应用程序服务器组成,它通过利用Web服务器执行动态任务。这一层交互通过数据库或某些外部程序数据层。
Data - 此层由数据库或任何来源的数据。
使用Node创建Web服务器
使用http.createServer方法创建HTTP服务器。通过它一个函数带参数请求和响应。编写一个示例实现返回一个请求页面。通过在8081端口上监听。
创建一个js文件名为server.js 在 D:\>yiibai_worksp\nodejs
File: server.js
//http module is required to create a web servervar http = require('http');//fs module is required to read file from file systemvar fs = require('fs');//url module is required to parse the URL passed to servervar url = require('url');//create the serverhttp.createServer(function (request, response) { //parse the pathname containing file name var pathname = url.parse(request.url).pathname; //print the name of the file for which request is made. //if url is http://localhost:8081/test.htm then //pathname will be /test.html console.log("Request for " + pathname + " received."); //read the requested file content from file system fs.readFile(pathname.substr(1), function (err, data) { //if error occured during file read //send a error response to client //that web page is not found. if (err) { console.log(err.stack); // HTTP Status: 404 : NOT FOUND // Content Type: text/plain response.writeHead(404, {'Content-Type': 'text/html'}); }else{ //Page found // HTTP Status: 200 : OK // Content Type: text/plain response.writeHead(200, {'Content-Type': 'text/html'}); // write the content of the file to response body response.write(data.toString()); } // send the response body response.end(); }); }).listen(8081);// console will print the messageconsole.log('Server running at http://127.0.0.1:8081/');
创建一个名为 test.html 的 html 文件在 D:\>yiibai_worksp\nodejs
File: test.html
<html><head><title>Sample Page</title></head><body> Hello World!</body></html>
现在运行server.js看到的结果:
D:\yiibai_worksp\nodejs>node server.js
验证输出。服务器已经启动
Server running at http://127.0.0.1:8081/
发出请求到Node.js服务器
在任何浏览器中打开以下网址:http://127.0.0.1:8081/test.html,看看下面的结果。
验证服务器端的输出
Server running at http://127.0.0.1:8081/Request for /test.html received.
使用Node创建Web客户端
Web客户端可以使用http模块来创建。参见下面的例子:
创建一个名为client.js的js文件在 D:\>yiibai_worksp\nodejs
File: client.js
//http module is required to create a web clientvar http = require('http');//options are to be used by request var options = { host: 'localhost', port: '8081', path: '/test.html' };//callback function is used to deal with responsevar callback = function(response){ // Continuously update stream with data var body = ''; response.on('data', function(data) { body += data; }); response.on('end', function() { // Data received completely. console.log(body); });}//make a request to the servervar req = http.request(options, callback);req.end();
现在运行client.js在不同的终端命令行,也就是在server.js以外终端上看到的结果:
D:\yiibai_worksp\nodejs>node client.js
验证输出:
<html><head><title>Sample Page</title></head><body> Hello World!</body></html>
验证服务器端的输出
Server running at http://127.0.0.1:8081/Request for /test.html received.Request for /test.html received.
Node.js - Express应用程序
Express 概述
Express JS是用于创建Node JS的Web应用程序非常流行的Web应用程序框架。它提供了一个集成的环境便于快速开发基于Node的Web应用程序。Express框架是基于连接的中间件引擎并使用Jade HTML模板框架来做HTML模板。以下是一些Express 框架的核心功能:
允许设立中间件来响应HTTP请求
定义了用于执行基于HTTP方法和URL不同作用的路由表
允许动态渲染基于参数传递给模板的HTML页面
安装Express
首先,使用NPM安装Express框架到全局,以便它可以使用Node终端来创建Web应用程序。
D:\yiibai_worksp\nodejs> npm install express -g
当npm完成下载,可以通过查看内容来验证,内容在 <user-directory>/npm/node_modules. 或输入以下命令:
D:\yiibai_worksp\nodejs> npm ls -g
将看到以下的输出:
C:\Documents and Settings\Administrator\Application Data\npm+-- express@4.11.2 +-- accepts@1.2.3 | +-- mime-types@2.0.8 | | +-- mime-db@1.6.1 | +-- negotiator@0.5.0 +-- content-disposition@0.5.0 +-- cookie@0.1.2 +-- cookie-signature@1.0.5 +-- debug@2.1.1 | +-- ms@0.6.2 +-- depd@1.0.0 +-- escape-html@1.0.1 +-- etag@1.5.1 | +-- crc@3.2.1 +-- finalhandler@0.3.3 +-- fresh@0.2.4 +-- media-typer@0.3.0 +-- merge-descriptors@0.0.2 +-- methods@1.1.1 +-- on-finished@2.2.0 | +-- ee-first@1.1.0 +-- parseurl@1.3.0 +-- path-to-regexp@0.1.3 +-- proxy-addr@1.0.6 | +-- forwarded@0.1.0 | +-- ipaddr.js@0.1.8 +-- qs@2.3.3 +-- range-parser@1.0.2 +-- send@0.11.1 | +-- destroy@1.0.3 | +-- mime@1.2.11 | +-- ms@0.7.0 +-- serve-static@1.8.1 +-- type-is@1.5.6 | +-- mime-types@2.0.8 | +-- mime-db@1.6.1 +-- utils-merge@1.0.0 +-- vary@1.0.0
Express生成器
现在使用NPM安装express生成器。express生成器用于使用express命令创建应用程序框架。
D:\yiibai_worksp\nodejs> npm install express-generator -g
将看到以下的输出:
D:\yiibai_worksp\nodejs>npm install express-generator -gC:\Users\Administrator\AppData\Roaming\npm\express -> C:\Users\Administrator\AppData\Roaming\npm\node_modules\express-generator\bin\expressexpress-generator@4.13.1 C:\Users\Administrator\AppData\Roaming\npm\node_modules\express-generator+-- sorted-object@1.0.0+-- commander@2.7.1+-- mkdirp@0.5.1 (minimist@0.0.8)
Hello world 示例
现在使用下面的命令创建一个示例应用程序 firstApplication:
D:\yiibai_worksp\nodejs> express firstApplication
将看到以下的输出:
create : firstApplication create : firstApplication/package.json create : firstApplication/app.js create : firstApplication/public create : firstApplication/public/javascripts create : firstApplication/public/images create : firstApplication/public/stylesheets create : firstApplication/public/stylesheets/style.css create : firstApplication/routes create : firstApplication/routes/index.js create : firstApplication/routes/users.js create : firstApplication/views create : firstApplication/views/index.jade create : firstApplication/views/layout.jade create : firstApplication/views/error.jade create : firstApplication/bin create : firstApplication/bin/www install dependencies: $ cd firstApplication && npm install run the app: $ DEBUG=firstApplication:* ./bin/www
进入 firstApplication 文件夹并使用下面的命令来安装 firstApplication 的依赖关系:
D:\yiibai_worksp\nodejs\firstApplication> npm install
将看到以下的输出:
debug@2.1.2 node_modules\debug+-- ms@0.7.0cookie-parser@1.3.4 node_modules\cookie-parser+-- cookie-signature@1.0.6+-- cookie@0.1.2morgan@1.5.1 node_modules\morgan+-- basic-auth@1.0.0+-- depd@1.0.0+-- on-finished@2.2.0 (ee-first@1.1.0)serve-favicon@2.2.0 node_modules\serve-favicon+-- ms@0.7.0+-- fresh@0.2.4+-- parseurl@1.3.0+-- etag@1.5.1 (crc@3.2.1)jade@1.9.2 node_modules\jade+-- character-parser@1.2.1+-- void-elements@2.0.1+-- commander@2.6.0+-- mkdirp@0.5.0 (minimist@0.0.8)+-- transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)+-- with@4.0.1 (acorn-globals@1.0.2, acorn@0.11.0)+-- constantinople@3.0.1 (acorn-globals@1.0.2)express@4.12.2 node_modules\express+-- merge-descriptors@1.0.0+-- cookie-signature@1.0.6+-- methods@1.1.1+-- cookie@0.1.2+-- fresh@0.2.4+-- utils-merge@1.0.0+-- range-parser@1.0.2+-- escape-html@1.0.1+-- parseurl@1.3.0+-- vary@1.0.0+-- content-type@1.0.1+-- finalhandler@0.3.3+-- serve-static@1.9.1+-- content-disposition@0.5.0+-- path-to-regexp@0.1.3+-- depd@1.0.0+-- qs@2.3.3+-- on-finished@2.2.0 (ee-first@1.1.0)+-- etag@1.5.1 (crc@3.2.1)+-- proxy-addr@1.0.6 (forwarded@0.1.0, ipaddr.js@0.1.8)+-- send@0.12.1 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)+-- accepts@1.2.4 (negotiator@0.5.1, mime-types@2.0.9)+-- type-is@1.6.0 (media-typer@0.3.0, mime-types@2.0.9)body-parser@1.12.0 node_modules\body-parser+-- content-type@1.0.1+-- bytes@1.0.0+-- raw-body@1.3.3+-- depd@1.0.0+-- qs@2.3.3+-- iconv-lite@0.4.7+-- on-finished@2.2.0 (ee-first@1.1.0)+-- type-is@1.6.0 (media-typer@0.3.0, mime-types@2.0.9)
在这里,express生成器创建了一个完整的应用程序结构,可以验证在 firstApplication 文件夹中(Nodejs_WorkSpace文件夹下面)里创建的文件夹/文件:
.+-- app.js+-- bin| +-- www+-- package.json+-- public| +-- images| +-- javascripts| +-- stylesheets| +-- style.css+-- routes| +-- index.js| +-- users.js+-- views +-- error.jade +-- index.jade +-- layout.jade
package.json 是应用程序描述符文件包含在依赖项列表中,应用程序使用 Node 的其他属性
app.js 包含了服务器的初始化代码
bin是用于存储在生产模式下的应用程序
public用于存储图像,样式表和JavaScript文件
routes 包含路由处理程序
views 包含HTML模板来生成Web应用各种视图
第一个应用程序
app.js 是基于 express 的应用核心引擎。让我们更新默认app.js包括端口信息,并使用它来创建一个服务器。添加以下行到app.js :
//set the server portapp.set('port', process.env.PORT || 3000);//create the server http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port'));});
更新 app.js
以下是app.js文件的全部内容
更新 app.js 文件的内容在 D:\>yiibai_worksp\nodejs\firstApplication.
File: app.js
var express = require('express');var path = require('path');var favicon = require('serve-favicon');var logger = require('morgan');var cookieParser = require('cookie-parser');var bodyParser = require('body-parser');var http = require('http');var routes = require('./routes/index');var users = require('./routes/users');var app = express();// view engine setupapp.set('port', process.env.PORT || 8891);app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'jade');// uncomment after placing your favicon in /public//app.use(favicon(__dirname + '/public/favicon.ico'));app.use(logger('dev'));app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false }));app.use(cookieParser());app.use(express.static(path.join(__dirname, 'public')));app.use('/', routes);app.use('/users', users);// catch 404 and forward to error handlerapp.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err);});// error handlers// development error handler// will print stacktraceif (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); });}// production error handler// no stacktraces leaked to userapp.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} });});http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port'));});module.exports = app;
现在运行app.js看到的结果:
D:\yiibai_worksp\firstApplication>node app
验证输出,服务器已经启动
Express server listening on port 8891
发出一个请求到firstApplication
在浏览器打开网址:http://localhost:8891/,看看下面的结果:
再次在浏览器打开网址:http://localhost:8891/users,看看下面的结果:
基本的路由
在app.js下面的代码绑定两个Route处理。
var routes = require('./routes/index');var users = require('./routes/users');...app.use('/', routes);app.use('/users', users);
routes - 路由(index.js), 路由处理程序处理所有请求,主页发出通过 localhost:8891
users - users (users.js), 路由处理来处理所有发出的请求 /users 通过 localhost:3000/users
以下是对应折代码:D:\>yiibai_worksp\nodejs\firstApplication\routes\index.js是由express生成器创建。
var express = require('express');var router = express.Router();/* GET home page. */router.get('/', function(req, res, next) { res.render('index', { title: 'Express' });});module.exports = router;
当Node服务器接收到一个主页的请求,express路由器渲染索引页是使用模板index.jade同时传递参数title的值为'Express'。以下是模板代码内容:D:\>yiibai_worksp\nodejs\firstApplication\views\index.jade
extends layoutblock content h1= title p Welcome to #{title}
Node.js - 加强第一个应用程序
概述
在这篇文章中,我们将加强Express第一个应用程序,创建 Express JS 应用程序:
显示所有用户的列表
显示一个特定的用户的细节
添加新的用户的详细信息
第1步:创建一个基于JSON数据库
首先,让我们创建一个用户示例JSON基础数据库。
创建一个名为 user.json 在一个 JSON 文件于 D:\>yiibai_worksp\nodejs\firstApplication
File: user.json
{ "user1" : { "name" : "mahesh", "password" : "password1", "profession" : "teacher" }, "user2" : { "name" : "suresh", "password" : "password2", "profession" : "librarian" }, "user3" : { "name" : "newuser", "password" : "password3", "profession" : "clerk" }}
第2步:创建特定的用户Jade视图
在创建一个 user 目录在 D:\>yiibai_worksp\node\firstApplication\views 如下视图:index.jade - 查看显示所有用户的列表。
new.jade - 视图显示一个表单来添加一个新用户。
profile.jade - 查看显示的用户的细节
创建一个index.jade在 D:\>yiibai_worksp\nodejs\firstApplication\views\users.
File: index.jade
h1 Usersp a(href="/users/new/") Create new userul - for (var username in users) { li a(href="/users/" + encodeURIComponent(username))= users[username].name - };
创建一个文件 new.jade 在 D:\>yiibai_worksp\nodejs\firstApplication\views\users.
File: new.jade
h1 New Userform(method="POST" action="/Users/addUser")P label(for="name") Nameinput#name(name="name")P label(for="password") Passwordinput#name(name="password")P label(for="profession") Professioninput#name(name="profession")Pinput(type="submit", value="Create")
创建一个文件 profile.jade 在 D:\>yiibai_worksp\nodejs\firstApplication\views\users.
File: profile.jade
h1 Name: #{user.name}h2 Profession: #{user.profession}
第3步:更新用户路由处理 users.js
更新文件 users.js 在 D:\>yiibai_worksp\nodejs\firstApplication\routes.
File: users.js
var express = require('express');var router = express.Router();var users = require('../users.json');/* GET users listing. */router.get('/', function(req, res) { res.render('users/index', { title: 'Users',users:users });});/* Get form to add a new user*/router.get('/new', function(req, res) { res.render('users/new', { title: 'New User'});});/* Get detail of a new user */router.get('/:name', function(req, res, next) { var user = users[req.params.name] if(user){ res.render('users/profile', { title: 'User Profile', user:user}); }else{ next(); } });/* post the form to add new user */router.post('/addUser', function(req, res, next) { if(users[req.body.name]){ res.send('Conflict', 409); }else{ users[req.body.name] = req.body; res.redirect('/users/'); } });module.exports = router;
现在运行app.js看到的结果:
D:\yiibai_worksp\nodejs\firstApplication>node app
验证输出,服务器已经启动
Express server listening on port 3000
发出请求到firstApplication得到所有用户的列表。在浏览器打开网址:http://localhost:8891/users,看看下面的结果。
点击创建新的用户链接看到表单。
提交表单并查看更新列表。
点击查看用户的详细。
可以检查服务器状态如下:
D:\yiibai_worksp\nodejs\firstApplication>node appExpress server listening on port 3000GET /users/ 200 809.161 ms - 201GET /users/new/ 304 101.627 ms - -GET /users/new/ 304 33.496 ms - -POST /Users/addUser 302 56.206 ms - 70GET /users/ 200 43.548 ms - 245GET /users/naresh 200 12.313 ms - 47
Node.js - Restful API
什么是REST架构?
REST表示代表状态传输。REST是基于Web标准的体系结构并使用HTTP协议。它围绕着资源,其中每一个组件是资源,资源是由一个共同的接口使用HTTP的标准方法获得。REST首先是由Roy Fielding在2000年推出。
在REST架构中,REST服务器只是提供获取资源,REST客户端访问和修改的资源。这里每个资源由URI标识的/全局ID。REST使用不同方式表示资源,如文本,JSON,XML。 JSON是最流行的一种。
HTTP 方法
以下四个HTTP方法通常用在基于的REST架构。
GET - 提供资源的只读访问
PUT - 用于创建一个新的资源
DELETE - 用于删除资源
POST - 用于更新现有的一个资源或创建新的资源
RESTful Web服务介绍
Web服务是用于交换应用程序或系统之间的数据开放的协议和标准的集合。写在各种编程语言的软件应用, 并在各种平台上运行可以使用Web服务以类似的进程间通信的方式在一台计算机上,通过计算机网络交换数据,如互联网。这种互操作性(如Java和Python,或Windows和Linux应用程序之间),是由于使用了开放标准。
基于REST架构的Web服务称为RESTful Web服务。这些Web服务使用HTTP方法来实现REST架构的概念。RESTful Web服务通常定义的URI,统一资源标识符的服务,提供资源的表示,如JSON,并设置HTTP方法。
为一个库创建RESTful
现在,我们将加强express示例应用程序,以下创建一个Web服务来用户管理:
获取所有用户信息
首先,让我们更新用户的样本基于JSON的数据库。
更新JSON文件名为user.json在 D:\>yiibai_worksp\nodejs\firstApplication.
File: user.json
{ "user1" : { "name" : "mahesh", "password" : "password1", "profession" : "teacher", "id": 1 }, "user2" : { "name" : "suresh", "password" : "password2", "profession" : "librarian", "id": 2 }, "user3" : { "name" : "ramesh", "password" : "password3", "profession" : "clerk", "id": 3 }}
当客户端发送GET请求/用户,服务器应该发送一个包含所有用户的响应。更新用户的路由处理,users.js
更新 users.js 在 D:\>yiibai_worksp\nodejs\firstApplication\routes.
File: users.js
/* GET users listing. */router.get('/', function(req, res) { res.send({ title: 'Users',users:users });});
添加新的用户的详细信息
当客户端发送一个POST请求 /users/addUser 包含JSON字符串,服务器应该发送一个响应声明状态。更新用户的路由处理users.js
更新 users.js 在 D:\>Nodejs_WorkSpace\firstApplication\routes.
File: users.js
/*add a user*/router.post('/addUser', function(req, res, next) { var body = ''; req.on('data', function (data) { body += data; }); req.on('end', function () { var json = JSON.parse(body); users["user"+json.id] = body; res.send({ Message: 'User Added'}); }); });
显示新用户的详细信息
当客户端发送GET请求到/users并带有id,服务器响应返回包含该用户的详细信息。更新用户的路由处理程序:users.js
更新 users.js 在 D:\>yiibai_worksp\nodejs\firstApplication\routes,如下:
File: users.js
router.get('/:id', function(req, res, next) { var user = users["user" + req.params.id] if(user){ res.send({ title: 'User Profile', user:user}); }else{ res.send({ Message: 'User not present'}); } });
完整的users.js 代码
File: users.js
var express = require('express');var router = express.Router();var users = require('../users.json');/* GET users listing. */router.get('/', function(req, res) { res.send({ title: 'Users',users:users });});router.get('/:id', function(req, res, next) { console.log(req.params) var user = users["user" + req.params.id] if(user){ res.send({ title: 'User Profile', user:user}); }else{ res.send({ Message: 'User not present'}); } });router.post('/addUser', function(req, res, next) { var body = ''; req.on('data', function (data) { body += data; }); req.on('end', function () { var json = JSON.parse(body); users["user"+json.id] = body; res.send({ Message: 'User Added'}); }); });module.exports = router;
输出
我们使用一个Chrome浏览器的扫插件:Postman, 来测试我们编写的 webservices,安装Postman需要到以下网址下载(可能需要翻墙):https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo 安装好这个插件后,打开后显示如下图:
现在运行app.js看到的结果:
D:\yiibai_worksp\nodejs\firstApplication> node app
验证输出。服务器已经启动
Express server listening on port 8891
提出一个请求到firstApplication获取所有用户的信息列表。把 http://localhost:8891/users 到POSTMAN 地址栏中,并使用GET请求,看到下面的结果。
发出一个请求到 firstApplication 以添加一个新用户。把 http://localhost:8891/users/addUser 放入到POSTMAN中并使用POST方式提交,看看下面的结果。
添加JSON数据格式,并选择POST方法。
{"name":"rakesh","password":"password4","profession":"teacher","id":5}
发出一个请求 firstApplication 获得用户。把 http://localhost:8891/users/1 在POSTMAN中找打开并用GET请求,看看下面的结果。
Node.js - 缩放应用
Node是在单线程模式下运行,它使用事件驱动的模式来处理并发。它还有助于创建子进程来利用并行处理在多核CPU的系统。
子进程始终有三个流child.stdin,child.stdout和child.stderr ,可以与父进程共享标准输入输出流。它们能够通过一个单独的流对象管道输送。
主要有三种方法来创建子进程。
exec - child_process.exec方法在shell/控制台运行一个命令并缓冲输出。
spawn - child_process.spawn由给定的命令启动一个新的进程
fork - child_process.fork方法是spawn() 创建Node进程的一个特例。
exec() 方法
child_process.exec方法在shell运行一个命令并缓冲输出。它签名如下:
child_process.exec(command[, options], callback)
command String要运行的命令,用空格分隔参数
options 对象
cwd 当前工作目录子进程的字符串
env 对象环境键值对
encoding 字符串(缺省:'utf8'')
shell 字符串Shell来执行(默认命令:在UNIX上在“/bin/sh”,在Windows为cmd.exe“,在shell中应该知道在Windows或UNIX/S/C-c开关。在Windows中,命令行解析应与cmd.exe兼容)
timeout 数字(默认值: 0)
maxBuffer 数字(默认值: 200*1024)
killSignal 字符串(默认值: 'SIGTERM')
uid 数字设置进程的用户身份
gid 数字设置进程的组标识
callback 当进程终止函数调用输出
error Error
stdout Buffer
stderr Buffer
Return:ChildProcess对象
exec() 返回一个缓冲器的最大尺寸,并等待该进程结束,并试图在一次返回所有缓冲的数据
示例
创建两个JS文件名为worker.js和master.js在 D:\>yiibai_worksp\nodejs
File: worker.js
console.log("Child Process "+ process.argv[2] +" executed." );
File: master.js
const fs = require('fs');const child_process = require('child_process');for(var i=0; i<3; i++) { var workerProcess = child_process.exec('node worker.js '+i, function (error, stdout, stderr) { if (error) { console.log(error.stack); console.log('Error code: '+error.code); console.log('Signal received: '+error.signal); } console.log('stdout: ' + stdout); console.log('stderr: ' + stderr); }); workerProcess.on('exit', function (code) { console.log('Child process exited with exit code '+code); });}
现在运行master.js看到的结果:
D:\yiibai_worksp\nodejs> node master.js
验证输出。服务器已经启动
Child process exited with exit code 0stdout: Child Process 1 executed.stderr:Child process exited with exit code 0stdout: Child Process 0 executed.stderr:Child process exited with exit code 0stdout: Child Process 2 executed.
spawn() 方法
child_process.spawn方法由给定的命令启动一个新的进程。它具有以下签名
child_process.spawn(command[, args][, options])
command 字符串 - 要运行的命令
args 字符串参数数组列表
options 对象
cwd 当前工作目录子进程的字符串
env 对象环境键值对
stdio 数组|子字符串的标准输入输出配置
customFds Array不推荐文件描述符由子进程使用标准输入输出
detached boolean值 - 子进程是一个进程组头进程
uid 数字设置进程的用户身份
gid Number设置进程的组标识
Return: ChildProcess对象
spawn() 返回流(标准输出与标准错误),并会使用当该过程返回大数据量。spawn()即开始接收到响应进程开始执行。
示例
创建两个JS文件名为worker.js和master.js在 D:\>yiibai_worksp\nodejs
File: worker.js
console.log("Child Process "+ process.argv[2] +" executed." );
File: master.js
const fs = require('fs');const child_process = require('child_process'); for(var i=0; i<3; i++) { var workerProcess = child_process.spawn('node', ['worker.js', i]); workerProcess.stdout.on('data', function (data) { console.log('stdout: ' + data); }); workerProcess.stderr.on('data', function (data) { console.log('stderr: ' + data); }); workerProcess.on('close', function (code) { console.log('child process exited with code ' + code); });}
现在运行master.js看到的结果:
D:\yiibai_worksp\nodejs> node master.js
验证输出。服务器已经启动
stdout: Child Process 0 executed.child process exited with code 0stdout: Child Process 2 executed.child process exited with code 0stdout: Child Process 1 executed.child process exited with code 0
fork 方法
child_process.fork方法是spawn() 的一个特例用来创建Node进程。它具有以下签名
child_process.fork(modulePath[, args][, options])
modulePath 字符串- 模块运行所在的子进程
args 字符串参数数组列表
options 对象
cwd 当前工作目录子进程的字符串
env 对象环境键值对
execPath 字符串可执行用于创建子进程
execArgv 传递给程序的可执行字符串参数数组列表(默认值:process.execArgv)
silent Boolean如果为true,stdin, stdout, 和 stderr 的标准错误将被输送到父进程,否则它们将继承自父,详情参见“管道”和“继承” 选项spawn()的标准输入输出(默认为false)
uid 数字设置进程的用户身份
gid 数字设置进程的组标识
Return: ChildProcess 对象
fork返回对象有内置的通信信道,除了具有正常的ChildProcess实例的所有方法。
示例
创建两个JS文件名为 worker.js 和 master.js 在 D:\>yiibai_worksp\nodejs
File: worker.js
console.log("Child Process "+ process.argv[2] +" executed." );
File: master.js
const fs = require('fs');const child_process = require('child_process'); for(var i=0; i<3; i++) { var worker_process = child_process.fork("worker.js", [i]); worker_process.on('close', function (code) { console.log('child process exited with code ' + code); });}
现在运行master.js看到的结果:
D:\yiibai_worksp> node master.js
验证输出。服务器已经启动
Child Process 0 executed.Child Process 1 executed.Child Process 2 executed.child process exited with code 0child process exited with code 0child process exited with code 0
- Node.js快速入门
- Node.js快速入门
- Node.js快速入门
- Node.js快速入门
- Node.js快速入门
- Node.js-入门一--快速入门
- 新手如何快速入门node.js
- Node.js入门之快速搭建开发环境
- node express 快速入门
- Node快速入门
- [Node.js]Linux 快速安装Node.js
- node.js入门学习
- node.js入门
- node.js 入门指导
- Node.js 入门
- node.js入门
- Node.js入门
- node.js入门
- tar.gz 和 tar.bz2 详细解释
- 上下DIV固定,中间DIV自适应的HTML+CSS实现
- JVM(1)——简介
- [模版] 带部分重构的KD_Tree
- 原理分析之二:框架整体设计
- Node.js快速入门
- Qt webEngine的前世今生
- 跟我学AngularJs:AngularJs内置指令大全
- 关于ubuntu的sources.list总结
- 柯志亨老师-- NS2 教學手冊
- 原理分析之三:初始化(配置文件读取和解析)
- Tomcat安装与配置
- Knight move
- 北京一日游感触