Search code examples
javascriptnode.jsnpmrcon

How to execute code after callback function has finished?


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);
});


});

Solution

  • 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(); While its not what I originally asked for in the title which is due to my mistake, it is what I was looking to do, make it work

    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);
    });