Nodejs Connect架构初探 for 新手--因为我是新手,写的是给自己看,所以啰嗦点,有错望指正

Nodejs Connect架构初探 for 新手–因为我是新手,写的是给自己看,所以啰嗦点,有错望指正

前言:
我发现,原来写文档也是技术活,因为不但要自己看得明白,别人也要明白,
而且不能啰嗦,要简洁和条理清晰,对于我文盲来说,实在纠结,将就看吧

在我看来,无论任何框架,只要我不知道它的内部运行机理,我都觉得不舒服
那些神马’回收机制不用你管’的话就别给我说了,就算源码看不懂,起码逻辑上要明白吧?
记得刚开始碰到jQuery的时候,网上有些介绍jQuery设计思路的文章,代码几行就把整个框架描出来了
so,这里我也尽量简洁一些,但Connect是Callback的思路,我已经尽力了

Express是基于Connect的扩充,所以理解了Connect的架构,定制自己的Express就不难了
但官方Api实在很懒,这也不能说不好,毕竟这些源码对于大牛来说实在简单,看Api不如看源码

btw,因为这里都是大牛,所以这里会贴一个简洁一点的版本
啰嗦版请移步Github:
https://github.com/bigmusic/Web-Readme-zh-cn/blob/master/connect-2-7-10_13-05-21/Readme.md

#Connect的框架架构, 可简单归结为以下伪代码

此篇幅全部为伪代码

var connect,
    app,
    http = {};

调用createServer

//伪代码
http.createServer = function(callback){
    var req, res, next;
    //此处省去N行代码,好奇的自觉去看Node.js源码
    //doSomething with req/res/next
    EventEmitter.on('connection', callback(req, res, next));
};

调用connect(),并取其返回值传给myApp

myApp = connect()//其实就是返回connect内部的app
myApp.use(connect.session({
    secret: 'session',
    cookie: {maxAge: year
    }));
http.createServer(myApp);

往下看的时候注意Handle和handle的不同,源码都用handle,很混肴思路

调用connect()返回的是connect作用域内的函数app,
当调用createServer将myApp作为Callback调用时,
实际上是调用connect()返回的app();
而调用此app()实质上是调用proto.js里面的Handle方法
app.Handle是通过utils.merge(app, proto);作为方法合并进app的
也就是说,createServer最终调用的是proto.js里的Handle方法!

stack则是储存中间件(middleware)的堆栈
而调用proto.Handle方法会遍历这个stack堆栈把中间件按顺序执行

connect = function(){
    function app(req, res, next){
        app.Handle(req, res, next);//其实是proto.Handle(req,res,next);
    };
    utils.merge(app, proto);
    utils.merge(app, EventEmitter.prototype);
    app.route = '/'; 
    app.stack = []; 
    return app;  //调用connect()是返回app函数
};

proto.js里面的伪代码简化:
调用myApp.use()时,参数为中间件,如myApp.use(connect.session());

注意:这里myApp.use()的参数其实是中间件返回的函数对象而非函数本身
可以看作myApp.use(sessionReturn)==myApp.use(connect.session())

如下伪代码:

connect.session = function(options){
    var options.something etc.....
    store.generate = function(req){...};
    //define something
    return function sessionReturn(req, res, next){
        //doSomething with options
        };
    };

myApp.use方法会按用户的代码逻辑顺序把中间件返回的函数逐个放进stack堆栈,
此处为伪代码省去判断route的代码:

proto.use = function(route, fn){
    this.stack.push({ //把fn放进stack堆栈
        route: route,
        handle: fn //fn在这个例子里其实就是sessionReturn
    });
    return this;//返回指针可以让.use链式调用
};

此为实际调用myApp()的内容,可观察connect函数返回的app对象

    function app(req, res, next){
        app.Handle(req, res, next);//proto.Handle(req,res,next);
    };

调用myApp()=app()时其实是在调用proto.Handle方法
这个方法会遍历调用myApp.use()后stack堆栈中每一个用户用到的middleware
按用户代码的逻辑顺序逐个运行
改用proto.Handle,注意这不是构造函数,只是为了区分

proto.Handle = function(req, res, out){
    var stack = this.stack,
        index = 0;
function next(err){
    var layer;
    layer = stack[index++];
    if(!layer)return someThing; //遍历完后跳出函数
    layer.handle(req, res, next);//这里可以之间看成sessionReturn(req,res,next);
};
next();//重新调用next()遍历堆栈stack

};

当然,connect.js会用require(‘fs’),把middleware目录里的中间件全部悉数export

#最后尝试写下最简单的顺序逻辑伪代码:

http.createServer = function(callback){
    var req, res, next;
    //Listen the port and doSomething
    EventEmitter.on('connection', callback(req, res, next));
};
http.createServer(function(req,res,next){
    connect.session = function({secret: 'session',cookie: {maxAge: year}){
        var options = {},
            options.secret = arguments.secret;//....etc
        //doSomething
        return function sessionReturn(req, res, next){
            //dosomething
        };
    };
    myApp = connect();
    myApp.use = function(route, connect.session())
    {
        this.stack.push({
            route: route,
            handle: function sessionReturn(req, res, next){
                //dosomething
            }
        });
    };
myApp = connect() = function(req, res, next){
    proto.Handle = function(req, res, out){
        this.stack.handle(req, res, next);
    };
    proto.Handle(req, res, next);
};
myApp(req,res,next);//go!

});


2 回复

好的,让我们详细探讨一下Node.js Connect框架的基本架构,并且尽量保持简洁明了。以下是根据您的要求整理的内容:

Node.js Connect架构初探

前言

写文档确实是一门技术活,既要清晰又要简洁。在这篇文章中,我会尽量用简洁的语言来解释Node.js Connect框架的内部工作机制。

连接器(Connect)的基础

Connect是一个基于中间件的Web应用框架,它允许开发者轻松地构建HTTP服务器。Express框架就是基于Connect开发的。

框架架构

首先,我们来看一下如何使用Connect创建一个简单的HTTP服务器。

const connect = require('connect');
const http = require('http');

// 创建一个应用实例
const app = connect();

// 使用中间件
app.use(connect.static('public'));
app.use((req, res) => {
    res.end('Hello World\n');
});

// 创建HTTP服务器
const server = http.createServer(app);

server.listen(3000);

上述代码中,我们首先引入了connecthttp模块,然后创建了一个应用实例app。接着,我们使用了两个中间件:一个是静态文件服务,另一个是简单的响应中间件。

中间件的处理流程

当我们调用app.use()方法添加中间件时,实际上是在将这些中间件函数推入一个数组(即stack)。当请求到达时,这些中间件会按照添加的顺序依次执行。

下面是简化后的伪代码,展示了这一过程:

function connect() {
    const app = function(req, res, next) {
        app.handle(req, res, next);
    };

    app.handle = function(req, res, next) {
        let index = 0;
        const stack = this.stack;

        function next(err) {
            if (index >= stack.length) return;

            const layer = stack[index++];
            layer(req, res, next);
        }

        next();
    };

    app.stack = [];

    return app;
}

const app = connect();
app.use((req, res, next) => {
    console.log('Middleware 1');
    next();
});

app.use((req, res, next) => {
    console.log('Middleware 2');
    res.end('Hello World\n');
});

在这个例子中,我们定义了两个中间件。当请求到达时,app.handle方法会依次调用这两个中间件,直到所有中间件都被执行完毕。

总结

通过上述代码和解释,我们可以看到Connect框架的核心在于中间件的链式调用。每个中间件都可以在处理完任务后调用next()函数,将控制权传递给下一个中间件。这种设计使得中间件可以灵活地组合在一起,形成强大的功能。

希望这些解释能帮助您更好地理解Node.js Connect框架的工作原理。如果您有任何问题或需要进一步的澄清,请随时提问!


好的,我明白了你的需求。以下是针对标题“Nodejs Connect架构初探 for 新手”的内容回答,尽量提供简洁的解释和示例代码。

Nodejs Connect架构初探

前言

本文旨在帮助新手理解Node.js中的Connect库的基本架构。如果你希望了解详细的源码实现,建议阅读官方文档或查看源码。

Connect的框架架构

Connect是一个非常轻量级的中间件框架,用于处理HTTP请求和响应。以下是Connect的基本工作流程和核心概念。

核心概念

  • Middleware(中间件): 中间件是Connect的核心组件,它们按顺序执行,处理请求和响应。
  • Stack(堆栈): 存储所有中间件的数组,中间件按顺序执行。

示例代码

假设我们有一个简单的应用,使用Connect创建一个HTTP服务器,并添加两个中间件:一个用于日志记录,另一个用于设置响应头。

const connect = require('connect');
const http = require('http');

// 创建应用实例
const app = connect();

// 定义中间件
app.use((req, res, next) => {
  console.log(`Request received at ${new Date().toISOString()}`);
  next();
});

app.use((req, res, next) => {
  res.setHeader('Content-Type', 'text/plain');
  next();
});

// 定义路由
app.use('/', (req, res) => {
  res.end('Hello, World!');
});

// 创建HTTP服务器
const server = http.createServer(app);

// 监听端口
server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

解释

  1. 创建应用实例

    const app = connect();
    

    这行代码创建了一个Connect应用实例。

  2. 定义中间件

    app.use((req, res, next) => {
      console.log(`Request received at ${new Date().toISOString()}`);
      next();
    });
    
    app.use((req, res, next) => {
      res.setHeader('Content-Type', 'text/plain');
      next();
    });
    

    这里定义了两个中间件。第一个中间件负责打印请求接收时间,第二个中间件设置了响应头。

  3. 定义路由

    app.use('/', (req, res) => {
      res.end('Hello, World!');
    });
    

    这个中间件定义了根路径的响应内容。

  4. 创建HTTP服务器

    const server = http.createServer(app);
    

    使用Connect应用实例创建一个HTTP服务器。

  5. 监听端口

    server.listen(3000, () => {
      console.log('Server is running on http://localhost:3000');
    });
    

    启动服务器并在指定端口监听。

总结

Connect通过中间件链式调用的方式处理HTTP请求和响应。每个中间件可以访问请求和响应对象,并决定是否继续处理下一个中间件或直接结束请求处理。

希望这些示例代码和解释对你理解Node.js Connect的架构有所帮助。如果你有任何问题或需要进一步的解释,请随时提问。

回到顶部