如何在Node.js脚本中进行同步DNS请求?

时间:2019-08-04 11:37:33

标签: node.js dns

我需要使用特定的DNS服务器在NodeJS程序中发出同步DNS请求(我需要实际请求,无需查找)。如果可能的话,我想使用标准的DNS库。我的代码在交互模式下工作,但不在实际脚本中工作。我对同步问题不太满意,因此我不完全了解等待和实际执行的操作。

这是我的代码,当前在我的脚本中:

var readline = require('readline-sync');

async function sendm(req, srv) {
    console.log("Will ask " + srv.getServers()[0] + " for " + req);
    const addresses = await srv.resolve4(req);
    console.log(addresses);
}

该功能在用户输入以“ s”开头的内容时执行:

const { Resolver } = require('dns').promises;
const dns = new Resolver();
dns.setServers(["8.8.8.8"]);
// ...

var input = "";
while(input != "q") {
        input = readline.question("Command: ");
        if(/^s/g.test(input)) { // input starts with s
                console.log("Input starts with s");
                sendm("stackoverflow.com", dns);
        }
        else if(/^r/g.test(input))
                console.log("input starts with r");
        // ...
}

以下是输出:

# nodejs debug.js
Command: s
Input starts with s
Will ask 8.8.8.8 for stackoverflow.com
Command: s
Input starts with s
Will ask 8.8.8.8 for stackoverflow.com
Command: s
Input starts with s
Will ask 8.8.8.8 for stackoverflow.com
Command: r
input starts with r
Command: r
input starts with r
Command: s
Input starts with s
Will ask 8.8.8.8 for stackoverflow.com
Command: q
[ '151.101.1.69', '151.101.65.69', '151.101.129.69', '151.101.193.69' ]
[ '151.101.1.69', '151.101.65.69', '151.101.129.69', '151.101.193.69' ]
[ '151.101.1.69', '151.101.65.69', '151.101.129.69', '151.101.193.69' ]
[ '151.101.1.69', '151.101.65.69', '151.101.129.69', '151.101.193.69' ]

我需要在程序仍在运行时处理DNS地址。我该怎么办?我尝试了在DNS库文档中找到的其他方法,但没有任何效果。你能帮我吗?

非常感谢!

2 个答案:

答案 0 :(得分:0)

基本上,您需要让while循环等待函数sendm的返回,我认为您可以将async放在while循环之前,然后将await放在函数之前,尽管相反将结果存储在addresses中的情况下,函数(sendm)应该返回该结果,这样它将返回已解决的Promise,然后才继续。如果您无法将一会儿包装在异步中,则将其粘贴在函数中,然后在函数调用sendm之前放置await。 需要明确的是,async表示该函数是异步执行的,await表示该函数返回一个已解决的Promise,并且直到达到该解析状态后才会继续执行。因此,这有点像在异步函数内部阻塞了同步代码。

答案 1 :(得分:0)

作为一个异步函数,sendm返回一个promise,但是while循环再次开始,因为它不知道promise,并且您可以发送一个新请求,而另一个请求则在等待调用中挂起。
虽然top level await尚未随节点一起提供,但是您可以将整个内容包装在异步IIFE中,该IIFE将适当地等待您的dns呼叫。

(async () => {
        var input = "";
        while(input != "q") {
                // ...
                        await sendm("stackoverflow.com", dns);
                // ...
        }
})();