如何使用Express.js 0.8.x域名表达?

时间:2012-07-22 11:07:28

标签: node.js express node.js-domains

如何创建将每个请求包装在自己的域中的Express / Connect中间件?

5 个答案:

答案 0 :(得分:12)

Speaker Deck上的这组幻灯片给出了一个简洁的概述:

从幻灯片中提取中间件代码:

var createDomain = require('domain').create;

app.use(function(req, res, next) {
  var domain = createDomain();

  domain.on('error', function(err) {
    // alternative: next(err)
    res.statusCode = 500;
    res.end(err.message + '\n');

    domain.dispose();
  });

  domain.enter();
  next();
});

答案 1 :(得分:12)

更新:下面介绍的方法已在connect-domain NodeJS模块中实施,该模块可用于Connect或Express应用程序。

从Express 3开始,express.createServer已弃用,其回调应转换为中间件。在中间件中,将请求和结果对象添加到请求域非常重要,以便由它们触发的错误由域错误处理程序处理。

我的中间件看起来像这样:

var domain = require('domain');

app.use(function(req, res, next) {
    var requestDomain = domain.create();
    requestDomain.add(req);
    requestDomain.add(res);
    requestDomain.on('error', next);
    requestDomain.run(next);
});

如果您从顶级域名中调用http.createServer,则可以避免将请求和响应添加到请求域,但域文档似乎表明每个请求域是最佳做法。

请注意,上面的代码不会执行任何域清理操作,例如强制处理请​​求域。我的中间件选择将错误再次通过中间件堆栈,以便稍后由特定的错误处理中间件处理。 YMMV。

答案 2 :(得分:5)

我有幸取代股票

var app = express.createServer();

使用:

var domainCreate = require('domain').create;
var app = express.createServer(function (req, res, next) {
    var domain = domainCreate();
    domain.run(next);
});

然后在中间件中,您可以向process.domain添加属性或添加其他错误处理。

答案 3 :(得分:2)

这是一个迟到的答案,但请查看express-domain-moddleware模块。它会自动为每个请求创建一个新域。您的路由中的process.domain可以引用活动域。这是一个例子:

//with domain-middleware
app.use(require('express-domain-middleware'));
app.use(app.router);

app.use(function errorHandler(err, req, res, next) {
  console.log('error on request %d %s %s: %j', process.domain.id, req.method, req.url, err);
  res.send(500, "Something bad happened. :(");
  if(err.domain) {
    //you should think about gracefully stopping & respawning your server
    //since an unhandled error might put your application into an unknown state
  }
});

app.get('/error', function(req, res, next) {
  db.query('SELECT happiness()', process.domain.intercept(function(rows) {
    fs.readFile('asldkfjasdf', process.domain.intercept(function(contents) {
      process.nextTick(process.domain.intercept(function() {
        throw new Error("The individual request will be passed to the express error handler, and your application will keep running.");
      }));
    }));
  }));
});

答案 4 :(得分:0)

域名目前已弃用:

https://nodejs.org/api/domain.html

为了分析错误',我创建了一个库,允许您以一种很好的方式编写异步代码:https://github.com/vacuumlabs/yacol。它的一个好处是你可以拥有类似域的行为,具有非常好的语义;看看这个!