Das liegt daran, dass der Code ein Anti-Pattern enthält:Jedes Mal, wenn eine neue Anfrage eingeht, öffnet er eine neue Datenbankverbindung und schließt diese Verbindung, sobald die Antwort gesendet wurde. Es hat dann anschließend versucht, die geschlossene Verbindung wiederzuverwenden, daher die Fehlermeldung, die Sie bei der zweiten Anfrage sehen.
Was Sie möchten, ist, sich nur einmal für die Lebensdauer der Anwendung mit einem globalen Verbindungsobjekt mit der Datenbank zu verbinden und dann dieses globale Objekt zu verwenden, um Ihre Datenbankoperationen auszuführen.
Durch die Verwendung dieses globalen Objekts kann der MongoDB-Treiber ordnungsgemäß einen Verbindungspool zur Datenbank erstellen. Dieser Pool wird vom MongoDB-Treiber verwaltet und vermeidet das teure Connect/Reconnect-Muster.
Zum Beispiel:
// listen on this port
const port = 3000
// global database client object
var client = null
// listen on the configured port once database connection is established
MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true }, (err, res) => {
assert.equal(null, err)
client = res
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
})
// use the client global object for database operations
app.get('/', (req, res) => {
db = req.query.db
col = req.query.col
client.db(db).collection(col).find({}).toArray((err, docs) => {
assert.equal(null, err)
res.send(JSON.stringify(docs))
})
})
Bearbeiten um deine Frage im Kommentar zu beantworten:
Dies liegt daran, dass im Originalcode dbClient
wurde global definiert. Wenn dbClient.close()
aufgerufen wurde, der globale dbClient
war geschlossen. Dann wurde ein Fehler erzeugt, wenn dbClient
Objekt wurde wiederverwendet. Das liegt daran, dass connect()
erstellt einen Verbindungspool anstelle einer einzelnen Verbindung und sollte nicht mehrmals pro Aufruf aufgerufen werden.
Wenn Sie den dbClient
verschieben Variable aus dem globalen Gültigkeitsbereich in app.get()
Kontext, werden Sie feststellen, dass kein Fehler erzeugt wird, wenn Sie den HTTP-Endpunkt mehrmals als neuen dbClient
aufrufen Objekt wurde jedes Mal erstellt.
Obwohl es funktionieren wird, ist dies jedoch kein empfohlenes Muster. Es ist besser, ein Muster zu verwenden, das dem Beispielcode ähnelt, den ich oben gepostet habe.