用于获取执行上下文的Node.js编程模式

时间:2012-03-29 11:31:01

标签: javascript design-patterns node.js express

我正在node.js中编写一个Web应用程序。现在,服务器上的每个处理始终位于会话的上下文中,该会话在请求到达服务器时的第一阶段检索或创建。在此之后,执行流经多个模块并在其中进行回调。我正在努力的是创建一个编程模式,以便在代码中的任何一点,会话对象都可用,而程序员不需要它在每个函数调用中将它作为参数传递。

如果所有代码都在一个文件中,我可能有一个闭包但如果有其他文件中的其他模块的函数调用我如何编程,以便会话对象在被调用的函数中可用而不传递给它一个论点。我觉得两个文件中的两个函数之间应该有一些联系,但如何安排就是我被卡住的地方。

一般情况下,我想说总有一个执行上下文可以是会话或网络请求,其处理分布在多个文件中,并且执行上下文对象将在所有点上可用。实际上可能有多个用例,例如每个网络请求有一个Log对象,或者每个会话有一个Log对象。并且需要进行这项工作所需的管道应该是横向安装的,而不需要应用程序员来解决它。他只知道所有地方都可以使用执行上下文。

我认为每个人都应该面对相当普遍的问题,所以请给我一些想法。

以下是问题

MainServer.js


  app = require('express').createServer();
  app_module1 = require('AppModule1');
  var session = get_session();
  app.get('/my/page', app_module1.func1);

AppModule1.js

  app_module2 = require('AppModule2');
  exports.func1 = function(req,res){

     //  I want to know which the session context this code is running for

     app_module2.func2(req,res);

   }

AppModule2.js

   exports.func2 = function(req,res){

    // I want to know where the session context in which this code is running

    }

4 个答案:

答案 0 :(得分:8)

您可以使用Domains - 一个新的节点0.8功能来实现此目的。我们的想法是在它自己的域中运行每个请求,为每个请求数据提供一个空间。您可以访问当前请求的域,而无需通过process.domain传递它。

以下是将其设置为使用express的示例: How to use Node.js 0.8.x domains with express?

请注意,域名一般都是实验性的,特别是process.domain是未记录的(尽管显然不会在0.8中消失,并且有一些关于使其成为永久性的讨论)。我建议按照他们的建议并向process.domain.data添加特定于应用程序的属性。

https://github.com/joyent/node/issues/3733

https://groups.google.com/d/msg/nodejs-dev/gBpJeQr0fWM/-y7fzzRMYBcJ

答案 1 :(得分:0)

由于您使用的是Express,因此可以将会话附加到每个请求。实施如下:

var express = require('express');
var app = express.createServer();
app.configure('development', function() {
  app.use(express.cookieParser());
  app.use(express.session({secret: 'foo', key: 'express.sid'}));
});

然后,在每次请求时,您都可以访问以下会话:

app.get('/your/path', function(req, res) {
  console.log(req.session);
});

我假设您希望每个会话都有某种唯一标识符,以便您可以跟踪其上下文。 SessionID可以在我们为每个会话设置的'express.sid'cookie中找到。

app.get('/your/path', function(req, res) {
  console.log(req.cookies['express.sid']);
});

基本上,除了添加cookie解析器并为您的快速应用程序启用会话之外,您不必执行任何其他操作,然后在将请求传递给这些功能时,您可以识别会话ID。你必须传递请求,你不能建立一个只知道会话的系统,因为你正在编写服务器并且会话可以根据要求提供。

答案 2 :(得分:0)

什么表达,以及在node.js上构建http堆栈的常见做法是使用http中间件来“增强”或向从服务器进入回调的请求和响应对象添加功能。这非常简单直接。

module.exports = function(req, res, next) {
    req.session = require('my-session-lib');
    next(); 
};

req和res会自动传递到您的处理程序中,您需要将它们保留在架构的相应层中。在您的示例中,它可以这样使用:

AppModule2.js

exports.func2 = function(req,res){

    // I want to know where the session context in which this code is running
    req.session; // <== right here

}

答案 3 :(得分:0)

Nodetime是一个分析工具,可以在内部执行您要执行的操作。它提供了一种功能,可以对您的代码进行检测,使得特定HTTP请求产生的调用与该请求相关联。例如,它了解请求在Mongo,Redis或MySQL中花费了多少时间。看一下网站上的视频,看看我的意思http://vimeo.com/39524802

库将探针添加到各种模块中。但是,我还没有看到它们之间如何传递上下文(url)。希望有人可以解决这个问题并发表解释。

编辑:抱歉,我认为这是一个红鲱鱼。 Nodetime正在使用堆栈跟踪将呼叫相互关联。它呈现的结果是对可能多次调用同一URL的聚合,因此这不是OP问题的解决方案。