Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

socket.io Emit events firing multiple times

I've read a few questions here on SO about this subject, but I'm not sure yet how to solve it in my case. The getMsgs emit event is firing as many times as I've accessed the /admin url. I know from other questions on SO that it is because the listener is registering every time I visit the admin page, but I'm not sure how to refactor my code (ie where to move the io.on(..) and how to call it from the router.get('/admin'..) function.

router.get('/admin', function(req, res, next){
    io.on('connection', function (socket) {
        dal.findAllMessages(function(err, messages) {
            console.log('sent msgs');
            socket.emit('getMsgs', messages);
        });

        socket.on('newMsg', function(data){
            console.log('newMsg');
            console.log(data);
            dal.addMessage(data);
            dal.findAllMessages(function(err, messages) {
                socket.emit('getMsgs', messages);
            });
        });

        socket.on('delMsg', function(data){
            console.log('delMsg');
            console.log(data);
            dal.deleteMessage(data);
            dal.findAllMessages(function(err, messages) {
                socket.emit('getMsgs', messages);
            });
        });
    });
    res.render('admin');
});
like image 221
DeepSpace Avatar asked Feb 09 '23 22:02

DeepSpace


1 Answers

Move the io.on(...) code outside of the route. You are re-registering a new event handler every time the /admin route is hit, thus you get multiple event handlers for the exact same events.

router.get('/admin', function(req, res, next){
    res.render('admin');
});

io.on('connection', function (socket) {
    dal.findAllMessages(function(err, messages) {
        console.log('sent msgs');
        socket.emit('getMsgs', messages);
    });

    socket.on('newMsg', function(data){
        console.log('newMsg');
        console.log(data);
        dal.addMessage(data);
        dal.findAllMessages(function(err, messages) {
            socket.emit('getMsgs', messages);
        });
    });

    socket.on('delMsg', function(data){
        console.log('delMsg');
        console.log(data);
        dal.deleteMessage(data);
        dal.findAllMessages(function(err, messages) {
            socket.emit('getMsgs', messages);
        });
    });
});

If you don't want the socket.io event handlers to be installed until the /admin route it hit, then you can keep a flag for whether they are set yet or not.

If you only want the socket.io event handlers to apply to specific admin clients, then you will need a different approach that uses some sort of authentication to decide whether a socket.io connection is allowed to connect or not.

like image 103
jfriend00 Avatar answered Mar 11 '23 08:03

jfriend00