Node.js Socket.io and Express: Sending data continuously to the client other than the setInterval method

StackOverflow https://stackoverflow.com/questions/23442187

  •  14-07-2023
  •  | 
  •  

Question

I've been fiddling around with socket.io and express. And I,m using Mongoose in this project. I have this code:

Server

io.on('connection', function (socket) {
    setInterval(function(){
        Data.find({}, {name:1, _id:0}, {sort : { _id : -1 }}, function (err, data) {
            if (err) {
                console.log(err);
            } else {
                socket.emit('data', {datas: data});
            };
        })
    }, 500);
});

Client

var socket = io.connect();
socket.on('data', function (data) {
    if (data) {
        $('#names').html('');
        $.each(data.datas, function (index, value) {
            $('#names').append('<li>'+ value.name +'</li>')
        })
    };
});

Is it proper to execute setInterval on socket.io connection to load the necessary data from the database to send it continuously to the client? Will this affect the server in performance? If it does, whats the best way to fetch data from mongodb to the client side continuously? Is there a way to watch (or something like database trigger) the collections in mongodb if someone from the user/client side adds data? In my code, Am I doing the right thing in placing the mongodb query inside the setInterval function? I'm new in using node.js, socket.io and mongodb. Can someone direct me to the right path? Thanks in advance!

Was it helpful?

Solution

Here is what I have accomplished rather than using the setInterval method in case someone wants to know how i did it on my project. Thanks to @Mariusz comment

"how about a simple HTTP webservice called by the one who writes to the database?"

gave me an idea. Instead, what I did is add an event click method on the form submit with socket.emit('client_data', {'data': $(this).serializeArray()}); to send the data to the server. Then on the server I call socket.on('client_data') method to fetch the data from the client to save it to the database and called io.sockets.emit method from the callback to send back the updated data to the client (reference on how to send responses to clients). Sorry if can't explain it even better, but here's the code so you could figure it out.

Client

<script src="/js/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<form id="form" method="post">
    <label for="name">Name: <input id="text"type="text" name="name"></label>
    <button id="submit" name="submit">save</button>
</form>
<ul id="names">
{% if datas %}
    {% for data in datas %}
    <li>{{data.name}}</li>
    {% endfor %}
{% else %}
    <li>No data</li>
{% endif %}
</ul>

<script>
$(document).ready(function(){
    var socket = io.connect();
    socket.on('data', function (data) {
        if (data) {
            $('#names').html('');
            $.each(data.datas, function (index, value) {
                $('#names').append('<li>'+ value.name +'</li>')
            })
        };
    });

    $('#form').on('submit', function(e){
        e.preventDefault();
        socket.emit('client_data', {'data': $(this).serializeArray()});
        $('#text').val('').focus();
    })
});
</script>

Server

io.on('connection', function (socket) {
    socket.on('client_data', function(data){
        Data.create({
            name: data.data[0].value
        }, function (err, newData) {
            console.log(newData.name + ' is now saved in the database.')
            Data.find({}, {name:1, _id:0}, {sort : { _id : -1 }}, function (err, data) {
                if (err) {
                    console.log(err);
                } else {
                    io.sockets.emit('data', {datas: data});
                };
            })
        })
    });
});

Now everytime a user/client updates the data, all the page will be updated as well without using setInterval to refresh the data. Hope it helps!

OTHER TIPS

Maybe you're better off with a messaging queue solution like RabbitMQ? This way you can send messages from one process to another and it is automatically notified. I've implemented notifications in an application using Node.js, socket.io and RabbitMQ (if it's near the area of your interest). It's an open-source project that I'll share if you want to (it's on GitHub but changes are not yet merged).

In any case, in situations like this, events are always better than polling (if only possible).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top