0

我不清楚如何顺序调用 Express 中间件。我希望下一个中间件只有在前一个完成后才会发生。我以为我必须调用 next() 才能发生,但显然情况并非如此。

mongoose.connect(app.set("db-uri"));

app.use(function(req, res, next) {
 if(1 !== mongoose.connection.readyState) {
    console.log('Database not connected');
    res.render("system/maintenance", {
      status: 500
    });
  } else {
    return next();
  }
});


// This middleware does not wait for the previous next(). It just tries to connect before actually.
app.use(express.session({
  secret: settings.sessionSecret,
  maxAge: new Date(Date.now() + 3600000),
  store: new MongoStore({ mongoose_connection: mongoose.connections[0], auto_reconnect: true })
}));

编辑:更新代码以仅在启动时连接 Mongoose 并检查中间件中的状态

4

2 回答 2

1

我承认这不是一个非常完整的答案,更不用说经过测试了,但它的要点应该有效。

首先,在启动应用程序时连接到数据库,例如不在中间件中。只需将这些moongoose.connect东西放在app.use某个地方之外(参见任何 mongoose+express 示例,例如这个)。

其次,我会使用一个“标志”来跟踪猫鼬是否已断开连接。

var mongooseIsConnected = false;

mongoose.on('open', function () {
  mongooseIsConnected = true;
});

mongoose.on('error', function () {
  mongooseIsConnected = false;
});

请注意,这在很大程度上是一种猜测。我不知道错误事件是否仅在连接失败时触发,同样我不知道重新连接时是否触发“打开”。如果您在某些文档中发现这一点,请告诉我,我会更新此答案。

最后,直接放置一个中间件——在任何其他使用数据库的中间件之前——检查标志是真还是假,然后传递请求或呈现错误。

app.use(function (req, res, next) {
  if(mongooseIsConnected) {
    next();
  }
  else {
    res.status(500);
    res.render('errorView');
    // Or you could call next(new Error('The database is broken')); and handle 
    // the error in a central express errorHandler
  }
});

// app.use(express.session etc here...

更新,在打开之前不使用猫鼬连接的解决方案:

mongoose.connect('uri...', configureApp);

function configureApp () {
  app.use(express.session({
    secret: settings.sessionSecret,
    maxAge: new Date(Date.now() + 3600000),
    store: new MongoStore({ mongoose_connection: mongoose.connections[0], auto_reconnect: true })
  }));

  // The other middleware and app.listen etc
}

这应该确保在定义中间件之前建立连接。但是,在挖掘我自己的代码时,我发现我只是让 MongoStore 创建了一个新连接。这可能更容易。

于 2013-08-29T18:09:10.133 回答
0

好的,这似乎有效。对这里的问题开放评论。

var store;
mongoose.connect(app.set("db-uri"));
mongoose.connection.on("connect", function(err) {
  // Create session store connection
  store = new MongoStore({ mongoose_connection: mongoose.connections[0], auto_reconnect: true });
});


app.use(function(req, res, next) {
  if(1 !== mongoose.connection.readyState) {
    console.log('Database not connected');
    // Try a restart else it will stay down even when db comes back up
    mongoose.connect(app.set("db-uri"));
    res.render("system/maintenance", {
      status: 500
    });
  } else {
    return next();
  }
});

app.use(express.session({
  secret: settings.sessionSecret,
  maxAge: new Date(Date.now() + 3600000),
  store: store
}));

似乎可以工作-我担心会话存储不会恢复,但我认为它可以工作。

于 2013-08-29T18:33:22.307 回答