Asynchronous server execution problem with Express, Mysql and Socket.IO

Asked

Viewed 389 times

2

I am developing a Node.JS project with Express, Mysql and Socket.IO. When the user opens the main page provided by the server, the request must cause data to be read from the database and sent to the client to be listed on the page.

The problem is that before the data can be sent, the server sends the page to the client and this causes the data not to be read from the BD or sent in the socket. I tried using async to make all the functions run in order, but it didn’t work.

My code:

app.all("/", function(req, res){ //Função para qualquer requisição HTTP (GET ou POST)

    var query1 = 'SELECT ? FROM tabela1;', query2 = 'SELECT ? FROM tabela2;';

    function qSelect(callback, queryTxt){ //Realiza queries de seleção no bd
        db.query(queryTxt, ['*'], function(err, results){
            if(err){
                console.log("Error on:");
                callback();
                return null;
            }
            callback();
            return results;
        });
    }

    async.series( //Executa comandos em série
        [qSelect(console.log("Table 1 data query."),query1), 
         qSelect(console.log("Table 2 data query."),query2),
         sendDataClient(console.log("Data sent to client."))], 

        function (err, output){ //Função executada após funções enfileiradas em série

            if(err){
                console.log("Error!! Sending database data to client did not result in success.");
                data = [null, null];
            } else{
                data = output;
            }

            io.on("connection", function(callback, socket){
                socket.emit("appData", {msg: "Schedule and Contact Data", content: data});
                socket.on("Return", function (data){
                    console.log(data.content);
                });
            });

        }

    );

res.sendFile("index.html"); //Envia página html ao cliente

});

In the case use Express exclusively to handle http pages and requests. Socket.IO is for sending binary data or text to be used in javascript on the client side.

  • Where are you calling the callback of this line io.on("connection"? I think you need to have the res.sendFile inside the callback of the async.series, how it’s going before the ascync series begin...

2 answers

1

I think this mixture of invoking io.on("Connection", ...) within the app.all() handler is wrong.

It is one thing for Express to serve the page; the other is Socket.IO to serve his requests. These are things that don’t mix. The client is probably trying the Socket.IO connection before you ran io.on("Connection",...) from the server side and the connection has already failed..

You probably wanted to start the query already during the index.html load, before the Socket.IO connection, but in exchange for what? Maybe make a few milliseconds?

The app.all(...) block should just send index.html. Move the whole block of io.on("Connection", ...) out of the app.all(...).

async.series(...) must be invoked within the io.on("Connection", ...) block, i.e., you only query Mysql when effectively the Socket.IO connection is effective, and the.Emit() socket is the last step.

The socket.on("Return", ...) must be called before async.series(...) because again it may happen that the customer sends Return before you have set up the respective handler, and the message is lost.

  • I have a Socket connection outside the request to establish the connection between the client and the server. My idea is to make the query whenever the client opens index.html to send the BD data to it.

1

I ended up solving my problem myself. After trying Q, as an alternative to async, I rewrote the code from scratch and managed to have the database query performed before, simply nesting the page delivery functions (express) and sending data (socket.) within the consultation function.

So the query is performed and then the page is sent to the client at the same time that the data obtained from the BD is sent by socket, updating the sent page.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.