使用node.js进行服务器端JavaScript编程(1)(3)
辅助模块
除了上面介绍的这些常见模块之外,node.js 还提供了一些辅助的模块。
模块 path 用来处理文件系统上的路径。这个模块中的 join() 用来把多个路径连接起来,形成一个完整的路径。如 join("/usr", "home", "test/index.html") 的结果是路径 /usr/home/test/index.html 。normalize() 用来对路径进行归一化操作,去掉其中多余的“/”以及处理“..”和“.”。resolve([from ...], to) 方法用来获取给定路径 to 的绝对路径。如果 to 不是绝对路径,就把它之前的参数按从右到左的顺序添加上去,直到得到了一个绝对路径。如果到最后还是无法得到绝对路径,就把当前的工作目录加上。假设当前的工作目录是 /usr/home ,那么 resolve("test", "index.html") 的返回结果是 /usr/home/test/index.html 。dirname() 方法用来获取路径的目录部分。如 dirname("/usr/home/index.html") 的返回结果是 /usr/home 。basename() 用来获取路径的最后一个部分。如basename("/usr/home/index.html") 的返回结果是 index.html 。extname() 用来获取一个路径的文件扩展名部分。如extname("/usr/home/index.html") 的返回结果是 .html 。
模块 url 用来对 URL 进行解析。parse(urlStr, parseQueryString) 方法用来把一个 URL 字符串 urlStr 解析成主机名、端口和路径等几个部分。该方法的返回值是一个包含了 protocol 、hostname 、port 、pathname 和 query 等属性的 JavaScript 对象。如果参数 parseQueryString 的值为 true 的话,URL 中包含的查询字符串部分也会被解析。format(urlObj) 方法的作用与 parse() 方法正好相反,用来从一个 JavaScript 对象中构建出 URL 字符串。
模块 querystring 用来处理 URL 中的查询字符串。stringify(obj) 方法用来把一个 JavaScript 对象 obj 转换成查询字符串的格式。如 stringify({a : 1, b : "good"}) 的返回结果是 a=1&b=good 。parse(str) 用来把一个查询字符串解析成 JavaScript 对象。
模块 vm 可以用来执行 JavaScript 代码。方法 runInThisContext(code) 用来执行一段 JavaScript 代码 code 并返回其结果。通过该方法运行的 JavaScript 代码不能访问当前代码的作用域。runInNewContext(code, [sandbox]) 方法也是用来执行 JavaScript 代码的,与 runInThisContext() 不同的是通过该方法运行的 JavaScript 代码使用 sandbox 对象作为全局对象。如 runInNewContext("a + 3", {a : 4}) 的返回结果是 7。createScript(code) 方法用来预先编译一段 JavaScript 代码,但是并不立即执行。该方法的返回值是一个 Script 对象。该对象同样有 runInThisContext() 和 runInNewContext([sandbox]) 两个方法,含义与上面提到的两个方法类似。
模块 os 提供了与底层操作系统相关的一些信息。包括 hostname() 用来获取操作系统的主机名;type() 用来获取操作系统的类型;release() 用来获取操作系统的发行版本号;uptime() 用来获取以秒计算的系统运行时间;cpus() 用来获取 CPU 的相关信息。freemem() 和 totalmem() 分别用来获取系统的内存总数和可用内存数。
模块 util 提供了一些常用的辅助方法。debug(string) 方法用来输出信息到标准错误流。log(string) 方法用来输出附带时间戳的信息到标准输出流。inspect(object, showHidden, depth) 方法用来输出一个对象的内部结构,参数 object 是要查看的对象,showHidden 表示是否查看对象的隐藏属性,depth 表示查看的对象层次结构的深度,默认值是 2。inherits(constructor, superConstructor) 方法用来实现 JavaScript 中基于原型的继承机制。
在介绍完 node.js 提供的常用模块之后,下面通过一个完整的示例来说明 node.js 的用法。
实例分析
这个实例实现的功能是动态监测服务器的内存使用状态,即内存的占用率。获取服务器上的内存占用率比较简单,只需要使用 os 模块提供的方法即可,即 freemem()/totalmem() 。为了能够实时的监测内存占有率,服务器需要实时的把数据传输给浏览器端。这里最好的实现方式是 HTML 5 中引入的 WebSocket 规范。该规范在 Firefox 4 和 Google Chrome 等新浏览器上得到了支持。同时服务器端也需要支持此规范。Socket.IO 在 node.js 上提供了对 WebSocket 规范的支持,包括服务器端和浏览器端代码。代码清单 9 给出了使用 Socket.IO 的服务器端代码。
清单 9. 监测内存占用率的服务器端代码
- var io = require('./socket.io');
- var io = io.listen(server);
- io.on("connection", function(client){
- setInterval(function() {
- client.send(os.freemem() / os.totalmem());
- }, 500);
- });
在 代码清单 9 中,server 是 node.js 中的一个 HTTP 服务器对象,用来响应一般的 HTTP 请求。Socket.IO 可以对 node.js 的 HTTP 服务器的请求进行拦截,将部分请求交给 Socket.IO 来处理。这里的处理逻辑是当有客户端连接上的时候,就每隔 500 毫秒把服务器的内存占用率发送给客户端。代码清单 10 给出了浏览器端的 HTML 和 JavaScript 代码。
清单 10. 监测内存占用率的浏览器端代码
- <!doctype html>
- <html>
- <head>
- <title> 服务器内存使用情况 </title>
- <script src="/socket.io/socket.io.js"></script>
- <style>
- #usage {border : 1px dashed green;}
- </style>
- <script>
- var canvas, width = 200, height = 200, buffer = [], max = 200;
- function updateChart(data) {
- if (buffer.length >= max) {
- buffer.unshift();
- }
- buffer.push(data);
- var ctx = canvas.getContext("2d");
- ctx.clearRect(0, 0, width, height);
- for (var i = 1, n = buffer.length; i < n; i++) {
- ctx.strokeStyle = "red";
- ctx.beginPath();
- ctx.moveTo(i - 1 , buffer[i - 1] * height);
- ctx.lineTo(i, buffer[i] * height);
- ctx.closePath();
- ctx.stroke();
- }
- }
- function onLoad() {
- canvas = document.getElementById("usage");
- var socket = new io.Socket(null, {port: 8088});
- socket.connect(); // 连接到服务器
- socket.on("message", function(obj){ // 接收到消息时的处理方法
- updateChart(obj);
- });
- }
- </script>
- </head>
- <body onload="onLoad();">
- <h1> 内存使用情况 </h1>
- <canvas id="usage" width="200" height="200"></canvas>
- </body>
- </html>
#usage {border : 1px dashed green;}
var canvas, width = 200, height = 200, buffer = [], max = 200;
function updateChart(data) {
if (buffer.length >= max) {
buffer.unshift();
}
buffer.push(data);
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, width, height);
for (var i = 1, n = buffer.length; i < n; i++) {
ctx.strokeStyle = "red";
ctx.beginPath();
ctx.moveTo(i - 1 , buffer[i - 1] * height);
ctx.lineTo(i, buffer[i] * height);
ctx.closePath();
ctx.stroke();
}
}
function onLoad() {
canvas = document.getElementById("usage");
var socket = new io.Socket(null, {port: 8088});
socket.connect(); // 连接到服务器
socket.on("message", function(obj){ // 接收到消息时的处理方法
updateChart(obj);
});
}
如 代码清单 10 所示,首先建立一个与服务器之间的 WebSocket 连接。通过 message 事件定义了当接收到服务器端的消息时,更新浏览器端的显示。浏览器端通过一个 HTML 5 提供的 canvas 来绘制内存占用率的曲线图,如 图 1 所示。
图 1. 内存占用率的曲线图

总结
一提到服务器端开发,开发人员一般想到的就是Java 和 C/C++ 等语言。但是通过 node.js 提供的强大能力,熟悉 JavaScript 的 Web 开发人员也可以开发出服务器端的应用。本文详细介绍了 node.js 的事件驱动机制和模块化结构,并对其中的常用模块做了详细说明,最后通过一个完整的实例展示了 node.js 的实用性。
原文:http://www.ibm.com/developerworks/cn/web/1107_chengfu_nodejs/index.html
- 上一篇:jQuery是如何工作的
- 下一篇:jQuery设计思想(1)