Reputation: 770
I'm building my first MERN app [a message board] and trying to add a mail notification using socket.io.
So far I have in server.js:
const io = socketio(expressServer);
const connectedUsers = {};
io.on('connection', (socket) => {
socket.emit('messageFromServer', { data: 'Welcome to the server' });
socket.on('messageToServer', (dataFromClient) => {
connectedUsers[dataFromClient.username] = socket;
});
});
to emit from my controller file, do I need the io object or just the socket, and how can I share it/them with the controller file?
All help greatly appreciated!
Upvotes: 1
Views: 1153
Reputation: 74680
Setup an external file for your user tracking connectedUsers.js
to avoid circular dependencies.
const connectedUsers = {}
module.exports = { connectedUsers }
Server Setup:
const { connectedUsers } = require('./connectedUsers')
io.on('connection', (socket) => {
socket.on('messageToServer', (dataFromClient) => {
connectedUsers[dataFromClient.username] = socket;
});
});
The next problem is getting the io
instance to the router/controller. I normally attach the io
instance to the app in the server setup for this.
app.io = io
Then in the router/controller you can access the io
instance from the req
object:
const { connectedUsers } = require('./connectedUsers')
router.post('/message', function(req,res){
if ( connectedUsers[req.body.username] && connectedUsers[req.body.username].id) {
const id = connectedUsers[req.body.username].id
req.app.io.to(id).emit({ msg: 'blah' })
}
})
The if
check above is an example of the code that will pop up everywhere you use connectedUsers
. The simple object often turns into a singleton class ConnectedUsers {}
instance so common code can be attached rather that littered throughout controllers.
Upvotes: 1