关于Node.js介绍,我们引用官网(http://nodejs.org/)的一段文字说明:
1 |
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. |
Google Chrome浏览器基于V8的,它是一个开源的JavaScript引擎,能够编译和执行JavaScript代码,在执行速度上有很大的优势。使用Node.js能够很容易地构建快速、可扩展的网络应程序,它使用了事件驱动、非阻塞I/O模型实现,具有轻量、高效的特点,适合于构建运行在分布地设备之上的数据密集型实时应用程序。
下面通过参考各种资料,从各个方面,概括地总结一下Node.js,是我们对Node.js有一个直观的了解:
- 使用JavaScript运行于服务端的平台上,自然继承了JavaScript语言的一些特性;
- Node.js基于单线程、基于非阻塞I/O模型实现;
- 适合于数据密集型应用,不适用于计算密集型类的应用(如算法等);
- 通过使用回调函数,来避免同步地等待I/O操作完成;
- Node.js非核心模块非常多,质量可能参差不齐(使用别人贡献的模块,要有承担风险的准备);
- 因为简单,开发Node.js应用程序效率很高;
- 调试相对困难,调试工具可能没有其他一些比较成熟的语言(如Java、C++等)的好用;
- Node.js基于事件驱动架构,events模块是Node.js最核心的模块。
我学习Node.js使用的工具及其环境配置,如下表所示:
工具/环境 |
版本 |
功能 |
Node.js |
0.10.28 |
Node.js平台 |
CentOS |
6.4 |
操作系统环境 |
npm |
1.4.9 |
Node包管理器(Node Package Manager) |
Python |
2.6.6 |
Node.js依赖环境(Linux系统下) |
Eclipse |
Kepler Service Release 2 |
Node.js调试工具 |
安装配置
安装步骤,如下所示:
3 |
sudo tar xvzf node-v0.10.28-linux-x64.tar.gz |
4 |
sudo ln -s /usr/local/node-v0.10.28-linux-x64 /usr/local/node |
5 |
sudo chown -R shirdrn:shirdrn /usr/local/node* |
配置内容:
2 |
export PATH=$PATH:/usr/local/node/bin |
Node包管理器(npm)
和Python等语言一样,在Node.js中可以使用npm来管理package,常用的命令,如下所示:
命令语法 |
说明 |
示例 |
npm -l |
显示npm命令的用法信息 |
npm -l |
npm install <pkg> |
安装包(package) |
npm install express |
npm install <pkg@version> |
安装指定版本的包 |
npm install express@4.4.3 |
npm ls |
显示已经安装的包 |
npm ls |
npm uninstall <pkg> |
卸载已经安装的包 |
npm uninstall express |
npm update [pkg] |
更新包 |
npm update或npm update express |
npm version |
查看npm版本号 |
npm version或npm -v |
npm list |
当前目录下已安装的包 |
npm list |
npm list -g |
当前系统下已经安装的包 |
npm list -g |
npm view <pkg> |
查看某个包的信息 |
npm view express |
npm view <pkg> version |
查看某个包的版本号 |
npm view express version |
npm view <pkg> dependencies |
查看某个包的依赖 |
npm view express dependencies |
npm outdated |
查看安装哪些包有新版本发布 |
npm outdated |
npm publish <tarball> |
发布包 |
npm publish mynodejs.tar |
npm unpublish <project>[@<version>] |
取消发布包 |
npm unpublish mynodejs@1.0.2 |
npm init |
初始化包(产生package.json) |
npm init |
npm tag <project>@<version> [<tag>] |
打tag |
npm tag mynodejs@1.1.0 stable |
使用上面的命令可以方便地管理Node.js包。
node工具
使用node工具运行Node.js脚本非常容易,语法格式如下所示:
1 |
node [options] [ -e script | script.js ] [arguments] |
有三种执行方式:
比如,运行脚本debug.js,执行如下命令即可:
如果,想要直接在命令执行代码段,可以使用-e选项,例如:
1 |
node -e 'console.log("hello")' ; |
其中-e选项后面是一个代码的字符串,他会转换成JavaScript代码在Node.js运行时环境执行,类似eval函数,将执行字符串中的代码。
可以直接根据输入node命令,然后回车,根据前导提示符,输入命令执行,一般用来测试比较直观。
调试Node.js代码
可以使用Eclipse开发工具,安装Chrome Developer插件:
http://chromedevtools.googlecode.com/svn/update/dev/
这个是在线安装地址。
例如,我们在Eclipse中新建一个debug.js文件,代码如下所示:
2 |
var customer = 'shirdrn' ; |
3 |
var f = function (name) { |
4 |
console.log( 'Hello, ' + name + '!' ); |
然后,在Shell终端启动调试:
1 |
node --debug-brk=9222 /home/shirdrn/nodejs/debug.js |
接着,可以在Eclipse中对debug.js的代码设置断点,执行Debug As => Debug Configurations => 选择Standalone V8 VM,创建一个调试配置,然后可以调试运行,在断点处查看变量的值。
编程实践
events模块是Node.js最核心的模块,通过使用该模块,可以了解Node.js的事件机制。下面代码是注册2个事件:一个是解析命令行传入参数的parseCommand事件,另一个是执行Shell命令的executeCommand事件。当脚本启动执行时,发射一个parseCommand事件,把命令行传递的参数传递给该事件函数,解析参数构造Linux下Shell命令行完成后,会发射一个executeCommand事件,去执行这个Shell命令。
实现代码,如下所示:
03 |
var process = require( 'process' ); |
04 |
var taskShell = require( 'task-shell' ); |
05 |
var events = require( 'events' ); |
06 |
var bash = '/bin/bash' ; |
09 |
var emitter = new events.EventEmitter(); |
11 |
emitter.on( 'parseCommand' , function (argv) { |
13 |
console.log( 'argv.length=' + argv.length); |
14 |
if (argv.length >= 2) { |
15 |
for ( var i=2; i<argv.length; i++) { |
16 |
shell += ' ' + argv[i]; |
17 |
console.log( 'shell=' + shell); |
20 |
console.log( 'Parsed shell cmd: ' + shell); |
22 |
emitter.emit( 'executeCommand' , shell); |
26 |
emitter.on( 'executeCommand' , function (shellCmd) { |
27 |
console.log( 'Execute shell cmd: ' + shellCmd); |
29 |
shellCmd = bash + ' ' + shellCmd; |
30 |
var shell = new taskShell(); |
31 |
shell.run([], {command : shellCmd}, console); |
32 |
console.log( 'Shell cmd executed.' ); |
36 |
console.log( 'Passed cmd line: ' + process.argv); |
37 |
emitter.emit( 'parseCommand' , process.argv); |
04 |
var host = '192.168.1.115' ; |
05 |
console.log( 'Confiugre: host=' + host + ', port=' + port); |
07 |
var http = require( 'http' ); |
08 |
var server = http.createServer( function (req, res) { |
09 |
res.writeHead(200, { 'Content-Type' : 'text/plain' }); |
10 |
res.end( 'Welcome to our site!!!' ); |
12 |
console.log( 'Server created: ' + server); |
14 |
server.listen(port, host); |
在运行前,首先要安装http模块:
然后运行脚本(debughttp.js):
访问http://192.168.1.115:8080/,可以看到响应的消息内容。
03 |
var express = require( 'express' ); |
05 |
app.use( function (req, res, next) { |
06 |
console.log( '%s : %s' , req.method, req.url); |
10 |
app.use( function (req, res, next) { |
11 |
res.send(200, { 'hit' : 'www.shiyanjun.cn' }); |
运行脚本,访问http://192.168.1.115:8080/,可以看到响应的JSON格式数据内容。扩展一下,你可以写一个HTML表单,通过表单提交数据到上面的地址,然后在代码中通过req来接收参数数据,然后进行处理,最后响应请求。
03 |
var fs = require( 'fs' ); |
04 |
var file = '/etc/passwd' ; |
05 |
var encoding = 'UTF-8' ; |
06 |
fs.readFile(file, encoding, function (err, data) { |
- 使用socket.io、socket.io-client、process、util模块
下面实现的脚本,是一个服务端和客户端简单会话的逻辑,脚本名称为endpoint.js,首先需要安装socket.io、socket.io-client、process这三个模块。
下面代码执行,可以通过从命令传递选项参数,选择启动服务器,还是连接到服务器,代码实现如下所示:
04 |
var host = '192.168.1.115' ; |
05 |
var util = require( 'util' ); |
07 |
var startServer = function () { |
08 |
var http = require( 'http' ); |
09 |
var server = http.Server(); |
10 |
var io = require( 'socket.io' )(server); |
11 |
io.on( 'connection' , function (socket) { |
12 |
console.log( 'Connected!' ); |
14 |
socket.emit( 'welcome' , { 'version' : '3.5.2' , 'token' : '32jfds456FDSOwewA219bMqx4lPsz2' }); |
15 |
socket.on( 'report' , function (data) { |
16 |
console.log( 'Reported data: ' + util.inspect(data)); |
18 |
console.log( 'Computed!' ); |
20 |
socket.on( 'close' , function () { |
21 |
console.log( 'Closed!' ); |
25 |
console.log( 'Start server.' ); |
26 |
server.listen(port, host); |
29 |
var startClient = function () { |
30 |
var client = require( 'socket.io-client' ); |
31 |
var socket = client( 'http://' + host + ":" + port); |
32 |
socket.on( 'welcome' , function (data){ |
33 |
console.log( 'Get welcome info from server: ' + util.inspect(data)); |
34 |
var version = data[ 'version' ]; |
35 |
var token = data[ 'token' ]; |
36 |
console.log( 'version=' + version + ', token=' + token); |
38 |
var reportData = { 'alive' : [ 'node-01' , 'node-06' , 'node-03' ], 'dead' : [ 'node-8' ]}; |
39 |
console.log( 'Report data: ' + util.inspect(reportData)); |
40 |
socket.emit( 'report' , reportData); |
45 |
var process = require( 'process' ); |
46 |
var argv = process.argv; |
47 |
console.log( 'Passed arguments: ' + argv); |
50 |
if ( 'server' == option) { |
52 |
} else if ( 'client' == option) { |
55 |
console.error( 'Unknown augment: ' + option + '!' ); |
启动服务器,执行如下命令行:
1 |
node endpoint.js server |
启动连接服务器,执行如下命令行:
1 |
node endpoint.js client |
首先要安装mysql、dateformat(格式化日期)模块:
下面是使用Node.js操作MySQL的代码实现:
03 |
var mysql = require( 'mysql' ); |
04 |
var util = require( 'util' ); |
05 |
var dateFormat = require( 'dateformat' ); |
08 |
'host' : '192.168.1.105' , |
11 |
'password' : 'shiyanjun' |
14 |
var connect = function () { |
15 |
var connection = mysql.createConnection(config); |
17 |
console.log( 'Succeed to connected: ' + util.inspect(connection)); |
19 |
throw new Error( 'Fail to connect MySQL database!' ); |
24 |
var query = function (sql, callback) { |
27 |
var connection = connect(); |
29 |
console.error(util.inspect(err)); |
33 |
connection.query(sql, callback); |
35 |
console.log( 'Connection closed!' ); |
39 |
var querySQL = 'SELECT id, host, port, updated_at FROM domain_db.traffic_proxy LIMIT 0,10' ; |
41 |
query(querySQL, function (err, rows, fields) { |
45 |
for ( var i=0; i<rows.length; i++) { |
47 |
var host = row[ 'host' ]; |
48 |
var port = row[ 'port' ]; |
49 |
var updatedAt = dateFormat(row[ 'updated_at' ], 'yyyy-MM-dd hh:mm:ss' ); |
50 |
console.log( 'Record: host=' + host + ', port=' + port + ', updatedAt=' + updatedAt); |
上面代码,从MySQL数据库中的一个表中查询数据,然后打印出来。
想进一步深入理解Node.js,可以参考相关文档,主要包括Node.js提供的一些特性,如继承(还有JavaScript具有的一些特性)。Node.js还有很多的模块,通过学习来开发自己Node.js应用程序。