深入浅出Node.js(七):Connect模块解析(之一)作者 田永强 发布于 2012年6月5日
Connect模块背景Node.js的愿望是成为一个能构建高速,可伸缩的网络应用的平台,它本身具有基于事件,异步,非阻塞,回调等特性,这在前几篇专栏中有过描述。
正是基于这样的一些特性,Node.js平台上的Web框架也具有不同于其他平台的一些特性,其中Connect是众多Web框架中的佼佼者。
Connect自身十分简单,其作用是基于Web服务器做中间件管理。至于如何如何处理网络请求,这些任务通过路由分派给管理的中间件们进行处理。
它的处理模型仅仅只是一个中间队列,进行流式处理而已,流式处理可能性能不是最优,但是却是最易于被理解和接受。基于中间件可以自由组合和插拔的情况,优
化它十分容易。 中间件让我们回顾一下Node.js最简单的Web服务器是如何编写的: var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337, '127.0.0.1'); 我们从最朴素的Web服务器处理流程开始,可以看到HTTP模块基于事件处理网络访问无外乎两个主要的因素,请求和响应。同理的是Connect的中间件也是扮演这样一个角色,处理请求,然后响应客户端或是让下一个中间件继续处理。如下是一个中间件最朴素的原型: function (req, res, next) { // 中间件 } 在中间件的上下文中,有着三个变量。分别代表请求对象、响应对象、下一个中间件。如果当前中间件调用了res.end()结束了响应,执行下一个中间件就显得没有必要。 流式处理为了演示中间件的流式处理,我们可以看看中间件的使用形式: var app = connect(); // Middleware app.use(connect.staticCache()); app.use(connect.static(__dirname + '/public')); app.use(connect.cookieParser()); app.use(connect.session()); app.use(connect.query()); app.use(connect.bodyParser()); app.use(connect.csrf()); app.use(function (req, res, next) { // 中间件 }); app.listen(3001); Conncet提供use方法用于注册中间件到一个Connect对象的队列中,我们称该队列叫做中间件队列。 Conncet的部分核心代码如下,它通过use方法来维护一个中间件队列。然后在请求来临的时候,依次调用队列中的中间件,直到某个中间件不再调用下一个中间件为止。 app.stack = []; app.use = function(route, fn){ // … // add the middleware debug('use %s %s', route || '/', fn.name || 'anonymous'); this.stack.push({ route: route, handle: fn }); return this; }; 值得注意的是,必须要有一个中间件调用res.end()方法来告知客户端请求已被处理完成,否则客户端将一直处于等待状态。 路由从前文可以看到其实app.use()方法接受两个参数,route和fn,既路由信息和中间件函数,一个完整的中间件,其实包含路由信息和中间件函数。路由信息的作用是过滤不匹配的URL。请求在遇见路由信息不匹配时,直接传递给下一个中间件处理。 app.use("/upload", connect.multipart({ uploadDir: path })); 加上精确的路由信息后,可以将问题减小。 MVC目录借助Connect可以自由定制中间件的优势,可以自行提升性能或是设计出适合自己需要的项目。Connect自身提供了路由功能,在此基础上,可 以轻松搭建MVC模式的框架,以达到开发效率和执行效率的平衡。以下是笔者项目中采用的目录结构,清晰地划分目录结构可以帮助划分代码的职责,此处仅供参 考。 ├── Makefile // 构建文件,通常用于启动单元测试运行等操作 ├── app.js // 应用文件 ├── automation // 自动化测试目录 ├── bin // 存放启动应用相关脚本的目录 ├── conf // 配置文件目录 ├── controllers // 控制层目录 ├── helpers // 帮助类库 ├── middlewares // 自定义中间件目录 ├── models // 数据层目录 ├── node_modules // 第三方模块目录 ├── package.json // 项目包描述文件 ├── public // 静态文件目录 │ ├── images // 图片目录 │ ├── libs // 第三方前端JavaScript库目录 │ ├── scripts // 前端JavaScript脚本目录 │ └── styles // 样式表目录 ├── test // 单元测试目录 └── views // 视图层目录 参考:
关于作者田永强,新浪微博@朴灵,前端工程师,曾就职于SAP,现就职于淘宝,花名朴灵,致力于NodeJS和Mobile Web App方面的研发工作。双修前后端JavaScript,寄望将NodeJS引荐给更多的工程师。兴趣:读万卷书,行万里路。个人Github地址:http://github.com/JacksonTian。 |
|