Node.js socket response request and socket recovery

I have the following 2 problems when querying sqlite3 database with node.js via socket connection:

  • with the node.js http client. I am requesting a node.js HTTP server, the sequence of results is mixed

  • from time to time I get socket forks, it doesn't play

Here is the server code:

var http = require('http'); var url = require('url'); var sqlite3 = require('sqlite3').verbose(); var counter = 0; //create sqlite database for testing var db = new sqlite3.Database("db.sqlite3"); db.serialize(function() { db.run("DROP TABLE IF EXISTS test"); db.run("CREATE TABLE IF NOT EXISTS test (ID INTEGER)"); var stmt = db.prepare("INSERT INTO test VALUES (?)"); for (var i = 1; i <= 10; i++) { stmt.run(i); } stmt.finalize(); }); db.close(); //run server http.createServer(function (req, res) { var queryData = url.parse(req.url, true).query; res.writeHead(200, {"Content-Type": "text/plain; charset=utf-8"});//, "connection": "keep-alive" var db = new sqlite3.Database(new Buffer(queryData.SQLServerAddress, "base64").toString('utf8')); db.serialize(function() { db.each(new Buffer(queryData.SQLStatement, "base64").toString('utf8'), function(err, row) { counter++; console.log(counter + " / " + JSON.stringify(row)); res.end(JSON.stringify(row).toString()); }); }); db.close(); counter = 0; }).listen(1337, '127.0.0.1'); console.log('Server running...'); 

And here is the client code:

 var http = require('http'); for(i=1;i<=10;i++){ var SQLServerAddress = new Buffer("db.sqlite3").toString('base64'); var SQLStatement = new Buffer("SELECT * FROM test WHERE ID=" + i).toString('base64'); var options = { host: "127.0.0.1", port: 1337, path: "/?SQLServerAddress=" + SQLServerAddress + "&SQLStatement=" + SQLStatement }; callback = function(response){ var str = ""; response.on("data", function (chunk){ str += chunk; }); response.on("end", function (){ console.log(str); }); } http.request(options, callback).end(); } 

I repeat the request 10 times as a "stress test", sort of ...

So what I get in the console, for example,

Server Console:

 1 / {"ID":1} 2 / {"ID":2} 3 / {"ID":5} 4 / {"ID":4} 1 / {"ID":3} 2 / {"ID":6} 1 / {"ID":7} 2 / {"ID":9} 3 / {"ID":10} 4 / undefined 

And the client console:

 {"ID":1} {"ID":2} {"ID":5} {"ID":4} {"ID":3} {"ID":6} {"ID":7} {"ID":9} {"ID":10} events.js:68 throw arguments[1]; // Unhandled 'error' event ^ Error: socket hang up at createHangUpError (http.js:1263:15) at Socket.socketCloseListener (http.js:1314:23) at Socket.EventEmitter.emit (events.js:123:20) at Socket._destroy.destroyed (net.js:357:10) at process.startup.processNextTick.process._tickCallback (node.js:244:9) 

My questions:

  • How to save the results in the correct order?
  • What can I do to prevent the socket from hanging?

Thanks in advance!

+4
source share
1 answer

Node.js is an event-based asynchronous environment.

Thus, starting a for loop that calls a function simply adds these functions to the processing queue, but does not wait for them to complete.

Thus, all your requests are launched in parallel, and there is no guarantee, which will be completed / transferred first. If you want to guarantee an order, you need to send requests synchronously. The code below has not been tested, but you should get this idea, only after one request finishes, the next one is started (this does not fit into the for loop).

 var count = 0; callback = function(response){ var str = ""; response.on("data", function (chunk){ str += chunk; }); response.on("end", function (){ if (count++ < 10){ http.request(options, callback).end(); } console.log(str); }); } http.request(options, callback).end(); 

Unfortunately, I'm not sure what the best way to recover from is due to a socket hanging error, but you can try to surround the http.request method with try / catch and just start a new request if the previous one caused an error.

0
source

Source: https://habr.com/ru/post/1447977/


All Articles