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
});
我收到此错误 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
});