Node.js入门学习笔记
关于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调试工具 |
安装配置
安装步骤,如下所示:
|
1
2
3
4
5
|
cd /usr/localsudo tar xvzf node-v0.10.28-linux-x64.tar.gzsudo ln -s /usr/local/node-v0.10.28-linux-x64 /usr/local/nodesudo chown -R shirdrn:shirdrn /usr/local/node* |
配置内容:
|
1
2
3
|
vi ~/.bashrcexport PATH=$PATH:/usr/local/node/bin. ~/.bashrc |
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,执行如下命令即可:
|
1
|
node debug.js |
- 运行代码
如果,想要直接在命令执行代码段,可以使用-e选项,例如:
|
1
|
node -e 'console.log("hello")'; |
其中-e选项后面是一个代码的字符串,他会转换成JavaScript代码在Node.js运行时环境执行,类似eval函数,将执行字符串中的代码。
- REPL模式运行
可以直接根据输入node命令,然后回车,根据前导提示符,输入命令执行,一般用来测试比较直观。
调试Node.js代码
可以使用Eclipse开发工具,安装Chrome Developer插件:
http://chromedevtools.googlecode.com/svn/update/dev/
这个是在线安装地址。
例如,我们在Eclipse中新建一个debug.js文件,代码如下所示:
|
1
2
3
4
5
6
|
// say hello examplevar customer = 'shirdrn';var f = function(name) { console.log('Hello, ' + name + '!');}f(customer); |
然后,在Shell终端启动调试:
|
1
|
node --debug-brk=9222 /home/shirdrn/nodejs/debug.js |
接着,可以在Eclipse中对debug.js的代码设置断点,执行Debug As => Debug Configurations => 选择Standalone V8 VM,创建一个调试配置,然后可以调试运行,在断点处查看变量的值。
编程实践
- 使用核心模块events
events模块是Node.js最核心的模块,通过使用该模块,可以了解Node.js的事件机制。下面代码是注册2个事件:一个是解析命令行传入参数的parseCommand事件,另一个是执行Shell命令的executeCommand事件。当脚本启动执行时,发射一个parseCommand事件,把命令行传递的参数传递给该事件函数,解析参数构造Linux下Shell命令行完成后,会发射一个executeCommand事件,去执行这个Shell命令。
实现代码,如下所示:
|
01
02
03
04
05
06
07
08
09
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
|
#!/usr/bin/env nodevar process = require('process');var taskShell = require('task-shell');var events = require('events');var bash = '/bin/bash';// create event emittervar emitter = new events.EventEmitter();// register event: 'parseCommand'emitter.on('parseCommand', function(argv) { var shell = ''; console.log('argv.length=' + argv.length); if(argv.length >= 2) { for(var i=2; i<argv.length; i++) { shell += ' ' + argv[i]; console.log('shell=' + shell); } } console.log('Parsed shell cmd: ' + shell); // emit emitter.emit('executeCommand', shell);});//register event: 'executeCommand'emitter.on('executeCommand', function(shellCmd) { console.log('Execute shell cmd: ' + shellCmd); if(shellCmd != '') { shellCmd = bash + ' ' + shellCmd; var shell = new taskShell(); shell.run([], {command : shellCmd}, console); console.log('Shell cmd executed.'); }});console.log('Passed cmd line: ' + process.argv);emitter.emit('parseCommand', process.argv); |
- 创建一个HTTP服务器
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
#!/usr/bin/env nodevar port = 8080;var host = '192.168.1.115';console.log('Confiugre: host=' + host + ', port=' + port);var http = require('http');var server = http.createServer(function(req, res) { res.writeHead(200, {'Content-Type' : 'text/plain'}); res.end('Welcome to our site!!!');});console.log('Server created: ' + server);server.listen(port, host); |
在运行前,首先要安装http模块:
|
1
|
npm install http |
然后运行脚本(debughttp.js):
|
1
|
node debughttp.js |
访问http://192.168.1.115:8080/,可以看到响应的消息内容。
- 使用express框架创建HTTP服务器
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
#!/usr/bin/env nodevar express = require('express');var app = express();app.use(function(req, res, next) { console.log('%s : %s', req.method, req.url); next();});app.use(function(req, res, next) { res.send(200, {'hit' : 'www.shiyanjun.cn'});});app.listen(8080); |
运行脚本,访问http://192.168.1.115:8080/,可以看到响应的JSON格式数据内容。扩展一下,你可以写一个HTML表单,通过表单提交数据到上面的地址,然后在代码中通过req来接收参数数据,然后进行处理,最后响应请求。
- 文件读写
|
01
02
03
04
05
06
07
08
09
10
11
12
|
#!/usr/bin/env nodevar fs = require('fs');var file = '/etc/passwd';var encoding = 'UTF-8';fs.readFile(file, encoding, function(err, data) { if(err) { console.error(err); } else { console.log(data); }}); |
- 使用socket.io、socket.io-client、process、util模块
下面实现的脚本,是一个服务端和客户端简单会话的逻辑,脚本名称为endpoint.js,首先需要安装socket.io、socket.io-client、process这三个模块。
下面代码执行,可以通过从命令传递选项参数,选择启动服务器,还是连接到服务器,代码实现如下所示:
|
01
02
03
04
05
06
07
08
09
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
|
#!/usr/bin/env nodevar port = 8080;var host = '192.168.1.115';var util = require('util');var startServer = function() { var http = require('http'); var server = http.Server(); var io = require('socket.io')(server); io.on('connection', function(socket) { console.log('Connected!'); // emit version infomation socket.emit('welcome', {'version' : '3.5.2', 'token' : '32jfds456FDSOwewA219bMqx4lPsz2'}); socket.on('report', function(data) { console.log('Reported data: ' + util.inspect(data)); // do something console.log('Computed!'); }); socket.on('close', function() { console.log('Closed!'); }); }); console.log('Start server.'); server.listen(port, host);};var startClient = function() { var client = require('socket.io-client'); socket.on('welcome', function(data){ console.log('Get welcome info from server: ' + util.inspect(data)); var version = data['version']; var token = data['token']; console.log('version=' + version + ', token=' + token); // do something var reportData = {'alive' : ['node-01', 'node-06', 'node-03'], 'dead' : ['node-8']}; console.log('Report data: ' + util.inspect(reportData)); socket.emit('report', reportData); socket.emit('close'); });};var process = require('process');var argv = process.argv;console.log('Passed arguments: ' + argv);var option = argv[2];if('server' == option) { startServer();} else if('client' == option) { startClient();} else { console.error('Unknown augment: ' + option + '!');} |
启动服务器,执行如下命令行:
|
1
|
node endpoint.js server |
启动连接服务器,执行如下命令行:
|
1
|
node endpoint.js client |
- 使用mysql模块连接MySQL数据库
首先要安装mysql、dateformat(格式化日期)模块:
|
1
2
|
npm install mysqlnpm install dateformat |
下面是使用Node.js操作MySQL的代码实现:
|
01
02
03
04
05
06
07
08
09
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
|
#!/usr/bin/env nodevar mysql = require('mysql');var util = require('util');var dateFormat = require('dateformat');var config = { 'host' : '192.168.1.105', 'port' : '3306', 'user' : 'shirdrn', 'password' : 'shiyanjun'};var connect = function() { var connection = mysql.createConnection(config); if(connection) { console.log('Succeed to connected: ' + util.inspect(connection)); } else { throw new Error('Fail to connect MySQL database!'); } return connection;}var query = function(sql, callback) { // connect to MySQL try { var connection = connect(); } catch(err) { console.error(util.inspect(err)); throw err; } // execute SQL queries connection.query(sql, callback); connection.end(); console.log('Connection closed!');}// query examplevar querySQL = 'SELECT id, host, port, updated_at FROM domain_db.traffic_proxy LIMIT 0,10';query(querySQL, function(err, rows, fields) { if(err) { throw err; } for(var i=0; i<rows.length; i++) { var row = rows[i]; var host = row['host']; var port = row['port']; var updatedAt = dateFormat(row['updated_at'], 'yyyy-MM-dd hh:mm:ss'); console.log('Record: host=' + host + ', port=' + port + ', updatedAt=' + updatedAt); }}); |
上面代码,从MySQL数据库中的一个表中查询数据,然后打印出来。
想进一步深入理解Node.js,可以参考相关文档,主要包括Node.js提供的一些特性,如继承(还有JavaScript具有的一些特性)。Node.js还有很多的模块,通过学习来开发自己Node.js应用程序。
参考链接
- http://nodejs.org/
- https://www.npmjs.org/
- https://www.npmjs.org/doc/
- https://www.npmjs.org/package/express
- https://github.com/visionmedia/express/wiki/New-features-in-4.x
- http://expressjs.com/4x/api.html
- https://www.npmjs.org/package/socket.io
- https://www.npmjs.org/package/socket.io-client
- https://www.npmjs.org/package/mysql
- https://github.com/felixge/node-mysql
- https://www.npmjs.org/package/dateformat
- Node Web Development(David Herron)
开源项目
下面是我找到的一些Node.js开源项目,可以选择其中一些,通过阅读代码来全面熟悉Node.js: