Home > Net >  How to execute code after callback function has finished?
How to execute code after callback function has finished?

Time:11-02

I need to know how do I execute line(s) of code after every callback function has ended.

I'm using rcon package to send a rcon command to a Half-Life Dedicated Server(HLDS) hosting Counter Strike 1.6 server and get the response back. Problem is sometimes the response is divided into parts(I think its due to connection with UDP, TCP doesn't work). First I used res.send() in conn.on() with event 'response' callback function but I got error saying can't send HTTP headers. I got to know about res.write(), it can save what I need and then use res.send() later. But I don't know where is the proper place in post I can use res.send() after all 'response' has come back. I tried using the command after conn.connect() and other places but it hasn't worked.

const express = require('express');
var Rcon = require('rcon');

const app = express();
const port = 3000;
app.use(express.urlencoded({extended: true}));

app.get("/", function(req,res){
  res.sendFile(__dirname   "/index.html");
});

app.post("/", function(req, res) {

    var resp = "";
    var ip = req.body.serverip;
    var pass = req.body.pass;
    var command = req.body.command;

    var options = {
      tcp: false,
      challenge: true
    };

    var conn = new Rcon(ip, 27015, pass, options);

    conn.on('auth', function () {
      // You must wait until this event is fired before sending any commands,
      // otherwise those commands will fail.
      console.log("Authenticated");
      console.log("Sending command:"   command);
      conn.send(command);

    });

    res.setHeader("Content-Type", "text/html; charset=UTF-8");
    res.write("<!DOCTYPE html><html><body>")
    conn.on('response', function(str)  {
        console.log("Response: " str);
        res.write(str);
    });

    conn.on('error', function (err) {
      console.log("Error: "   err);
    });

    conn.on('end', function () {
      console.log("Connection closed");
      process.exit();
    });

    conn.connect();
    res.end("Done</body></html>");
});

app.listen(port, function(){
  console.log("Server is listening on port "  port);
});


});

CodePudding user response:

If you want to "stream" the response parts to an HTML page, you can use the following:

res.setHeader("Content-Type", "text/html; charset=UTF-8");
res.write("<!DOCTYPE html><html><body>"); // start an HTML page
conn.on('response', function(str) {
  res.write(str);
});

The rudimentary start of the HTML page, which you issue even before the first response comes in, causes the browser to display the text of incoming responses as you write them to the page. (See also here.)

If you can recognize the last response, you could finish the page with

conn.on('response', function(str) {
  res.write(str);
  if (str is the last response)
    res.end("</body></html>");
});

but the "response streaming" works even if there is no "last" response: in this case, the browser keeps waiting for more, so the page never finishes, but you can still read what is on it so far.

CodePudding user response:

Looking at this answer made me figure it out. I simply needed to remove conn.send() from auth and use it with a timeout after conn.connect(). Same with the response, a timeout and then use res.end();

app.post("/", function(req, res) {

    var ip = req.body.serverip;
    var pass = req.body.pass;
    var command = req.body.command;

    var options = {
      tcp: false,
      challenge: true
    };

    var conn = new Rcon(ip, 27015, pass, options);


    conn.on('auth', function () {
      // You must wait until this event is fired before sending any commands,
      // otherwise those commands will fail.
      console.log("Authenticated");
      console.log("Sending command:"   command);
      // conn.send(command);

    });
    conn.on('response', function(str)  {
        console.log("Response: " str);
        res.write("Response: " str);
    });
    conn.on('error', function (err) {
      console.log("Error: "   err);
      res.sendFile(__dirname   "/failure.html");
    });
    conn.on('end', function () {
      // res.end("Done</body></html>");
      console.log("Connection closed");
      process.exit();
    });

    res.setHeader("Content-Type", "text/html; charset=UTF-8");
    res.write("<!DOCTYPE html><html><body><pre>")  
    conn.connect();
    setTimeout(function(){
      conn.send(command);
    },1000);

    setTimeout(function(){
      res.end("Done</pre></body></html>");
    }, 2000);
});

CodePudding user response:

there is a module in node that turns callbacks into promises to facilitate these types of fn

https://nodejs.org/dist/latest-v8.x/docs/api/util.html

  • Related