MongoDB + Express 无法使用已结束的会话

MongoDB + Express cannot use a session that has ended

我收到此错误 MongoExpiredSessionError: Cannot use a session that has ended

我试过类似问题中提出的答案,他们主要建议使用await关键字。但是正如您将在下面的代码中看到的那样,我已经为我的所有数据库函数设置了该关键字。

我正在使用代理连接服务器和客户端 (React)。 有时它工作正常,但是当我更新我的客户端中的一些代码时,由于某种原因服务器会抛出这个错误。然后,当我在我的服务器文件中编辑某些内容时,它又开始正常工作(直到我在客户端中编辑某些内容)。我猜问题出在我使用代理的事实。

我按照 this tutorial 了解如何使用节点 js 服务器设置 React 应用程序。让我知道是否有更好的选择。

这是我的代码:

app.post("/getSubscribers", (req, res) => {
  var ssn = req.session;

  req.on("close", function(err1){
    console.log("Connection closed (getSubscribers)");
    console.log(err1);
  })

  if(!ssn.logged_in){
    res.send(JSON.stringify("loggedout"));
  }else{
    (async () => {
        try{
            await client.connect();

            console.log("1 (getSubscribers)");
            const db = await client.db("data");
            console.log("2 (getSubscribers)");
            const collection = await db.collection("subscribers");
            console.log("3 (getSubscribers)");
            const query = {user_id: ssn.user_id};
            console.log("4 (getSubscribers)");
            const cursor = await collection.find(query);
            console.log("5 (getSubscribers)");
            const result = await cursor.toArray();
            console.log("6 (getSubscribers)");
            const count = await cursor.count();
            console.log("7 (getSubscribers)");
            const data = {data: result, count: count}
            console.log("8 (getSubscribers)");

            
            res.send(JSON.stringify(data));
            console.log("9 (getSubscribers)");
        }catch(err){
            console.log("ERROR (getSubscribers)");
            console.log(err);
        }finally{
            console.log("Closing (getSubscribers)")
            await client.close();
        }
    })();
  }
});

这是错误信息:

[0] 1 (getSubscribers)
[0] 2 (getSubscribers)
[0] 3 (getSubscribers)
[0] 4 (getSubscribers)
[0] 5 (getSubscribers)
[0] ERROR (getSubscribers)
[0] MongoExpiredSessionError: Cannot use a session that has ended
[0] Closing (getSubscribers)

有时停在#5,有时停在#6。

正如我提到的,问题可能与服务器的设置方式有关,请查看 link 并告诉我这是设置服务器的好方法还是我应该这样做做不同的事。

每次向 /getSubscribers 请求时,您都会 connecting/disconnecting 访问您的数据库。因此,结束会话的一个原因可能是,如果在您的服务器上收到多个请求,则在处理另一个请求时,第一个请求的基础连接将关闭。

无论如何,在每次请求时都连接到您的数据库没有多大意义,您应该在启动 express-app 时连接到您的数据库。我会像他们在 official tutorial:

中那样使用类似的东西
// file ./db/conn.js

const { MongoClient } = require('mongodb');   
const client = new MongoClient(<tbd>, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

let dbConnection;

module.exports = {
  connectToServer: (callback) => {
    client.connect(function (err, db) {
      if (err || !db) {
        return callback(err);
      }

      dbConnection = db.db('<tbd>');
      console.log('Successfully connected to MongoDB.');

      return callback();
    });
  },

  getDb: () => {
    return dbConnection;
  },
};

然后您可以在主 app.js 文件中像这样使用它:

const app = express();
// ...
// get MongoDB driver connection
const dbo = require('./db/conn');

// perform a database connection when the server starts
dbo.connectToServer((err) => {
  if (err) {
    console.error(err);
    process.exit();
  }

  // start the Express server
  app.listen(PORT, () => {
    console.log(`Server is running on port: ${PORT}`);
  });
});

app.post("/getSubscribers", async (req, res) => {
  const ssn = req.session;

  if(!ssn.logged_in){
    return res.send(JSON.stringify("loggedout"));
  }
  
  const collection = await dbo.getDb().collection("subscribers");
  // rest of your code above
});