问题
I'm using react js for building frontend for a website. An express server (which is a microservice) sits in between the front end and MongoDB. I make Axios calls from react js to express server (URL = http://localhost:5688/chat ) using GET, POST, PUT whenever and wherever needed.
something like below
Client side
var resp = axios.get(`http://localhost:5688/chat`);
resp.then((response) => {
this.setState({data: response.data})
})
Server side
app.js
var app = express();
app.get('/chat', function (req, res) {
try {
var MongoClient = require('mongodb').MongoClient;
var url = '***********';
MongoClient.connect(url, { useUnifiedTopology: true }, function(err, client) {
if (err){
console.log('error occured while connection to databse ' + err);
}
else{
db.collection(collectionName).find({}).toArray(function(err, result){
if (err) {throw err;}
else{
client.close();
res.join(result); // the result would contain the data fetch from db and will be returned to my axios call
}
});
}
});
}
catch (ex) {
res.json(ex);
}
});
app.listen(5688, function(){
console.log('Server listening at http://localhost:5688');
});
Above is how I've implemented a GET call. Similarly, I've implemented POST and PUT methods as well.
PS: I removed a lot of intermediate code which is not very helpful for this question
Now I want to use MongoDB change stream to listen to all changes that happen to my collection on MongoDB. I'm aware of the tutorials that show how we can log the updated documents in the express server.....such as this tutorial. This makes it possible for my express server to get all the updated documents whenever data in my DB is changed.
But what I'm not sure about is how I can pass this new data to my client so that I can update my react component's state with this new data.
How do I make my frontend code sitting in my browser continuously listen to my express server (a REST API) which is already continuously listening to all changes in MongoDB with the help of change streams?
Is socket the only way to make my client continuously listen to my server? if so, how would I pass the new data coming from MongoDB streaming to the socket on the express server
Please let me know if I should provide more details. Thank you so much.
回答1:
I will give you an example from my own project in production:
//Server-side
//Assume tweetDB is the DB
//Assume you have socket.io setup
//MongoDB Change Stream
const changeStream = tweetDB.watch();
changeStream.on('change', (changes) => {
//Add a event emitter
socket.compress(true).emit('mongoStream',changes);
});
//Client-side in a js file or a script tag
//Assuming you have established a WebSocket connection already
//Add an event listener to listen for back end changes.
socket.on('mongoStream',data=>{
console.log(data)
});
//Note: Socket.io is event-driven.
//Add an event emitter
socket.emit('eventName','dataToEmit');
//Add an event listener
socket.on('eventName',data=>{
//Process the data here
});
回答2:
Is socket the only way to make my client listen to my server?
Well, yes. a socket connection is the only way you'll have to use something like socket.io or other socket implementation to do so.
However nodejs
concept is the opposite of maintaining socket
connections as that can become expensive when your connections amount scale up.
I feel the better more reliable solution is to ask the server every x
seconds (2-3?) "has changes been made" and if so update the view.
With that said, depending on the exact state your saving on your app this might be not viable as a solution.
来源:https://stackoverflow.com/questions/61344049/how-to-use-mongodb-change-streams-with-node-js-via-a-rest-api-microservice-buil