28

I have a loop that querys a database continuously. When the query returns a result, the node.js app will send a message to every client connected to the node server via socket.io v0.8.

Problem: io.sockets.broadcast.send('msg') is called in the middle of a setInterval() loop so it is not within an io.sockets.on()'s callback function and thus this will not work. When io.sockets.send('msg') is used, no message seems to be sent to the client.

Node.js code

setInterval(function() {
    util.log('Checking for new jobs...');
    dbCheckQueue(function(results) {
        if (results.length) {
            io.sockets.broadcast.send('hello');
        }
    });
}, 10*1000);

However, if the setInterval is to be called from within io.sockets.on('connection',..), every connected client will create an additional loop!

Node.js code

io.sockets.on('connection', function(socket) {
    setInterval(function() {
        util.log('Checking for new jobs...');
        dbCheckQueue(function(results) {
            if (results.length) {
                io.sockets.send('hello');
            }
        });
    }, 10*1000);
});

Clientside JS

        socket.on('hello', function() {
            console.log('HELLO received');
        })

*How can I get a SINGLE loop to run, but still be able to send a message to all connected clients?

Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
  • 2
    `io.sockets` can be accessed outside of `io.sockets.on`. – Eliasdx Nov 26 '11 at 20:29
  • 1
    @Eliasdx When I use `io.sockets.broadcast.send('hello')` outside, I get the error `TypeError: Cannot call method 'send' of undefined` – Nyxynyx Nov 26 '11 at 20:32
  • 2
    you can only use `broadcast` on a `socket`, e.g. `socket.broadcast.send` within a `io.sockets.on`-callback. however i think you can send to all clients with `io.sockets.send` (with `io.` and without `broadcast`). – Eliasdx Nov 26 '11 at 20:33
  • It appears that none of the clients can receive it if I use `io.sockets.send('hello')` – Nyxynyx Nov 26 '11 at 20:34
  • 1
    Hum. if you want to use `socket.on('hello',...)` you must use `socket.emit` instead of `socket.send`. – Eliasdx Nov 26 '11 at 20:37
  • If I want to send a message to all clients outside of the `io.sockets.on` callback function, is `io.sockets.send()` the only function I can use? If so, what should I use on the client side instead of `socket.on('hello', ...)` – Nyxynyx Nov 26 '11 at 20:40
  • 3
    Just use `io.sockets.emit('hello')` to send the msg. http://socket.io/#how-to-use – Eliasdx Nov 26 '11 at 20:41
  • Could you tell me how & where to put the `io.sockets.emit('some_link')` in my question - [https://stackoverflow.com/questions/45435498/how-to-use-socket-ioemit-function-outside-of-socket-function-nodejs-express](https://stackoverflow.com/questions/45435498/how-to-use-socket-ioemit-function-outside-of-socket-function-nodejs-express) ? – Deepak M Aug 01 '17 at 11:25

2 Answers2

40

I think that this will successfully solve your problem

io.sockets.emit('hello')
Cody Guldner
  • 2,888
  • 1
  • 25
  • 36
Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
2

Improving previous answer from @Nyxynyx

io.sockets.emit('hello')

It is equivalent to:

io.of('/').emit('hello');

If you need a different route, change the of function parameter.

Documentation: https://socket.io/docs/v3/server-api/index.html#server-sockets

Carlos Oliveira
  • 846
  • 10
  • 23
  • For anyone in the future: `io.of('/').emit('hello');` is actually the better function to use if you're using the redis adapter and rooms: `io.of('/').adapter.remoteJoin(user.socket_id, data.conversation.id);`. The reason being is that `io.sockets` will emit for every person that joins a room. – Kyle Corbin Hurst Nov 15 '21 at 18:36