NodeJS (Express + PUG) MVC 端口检查器

Posted

技术标签:

【中文标题】NodeJS (Express + PUG) MVC 端口检查器【英文标题】:NodeJS (Express + PUG) MVC Port Checker 【发布时间】:2020-04-08 02:24:02 【问题描述】:

我正在本地项目中通过检查端口响应状态来检查应用程序的可用性。

我已经自己编写了解决方案,但是它没有按我的预期工作,所以我在论坛上找到了一些代码。 让我快速描述一下我希望它如何工作。

从 MSSQL 数据库中获取服务器列表(主机名 + 端口)。 (已经可以了) 通过 ping/telnet/tcp 目标检查应用程序响应。 在网站上显示结果

Serverlist 将包含大约 200-300 个要检查的目的地,所以我想做一些在网站上异步显示检查结果的东西(目前它的工作方式是首先应用程序检查所有结果,然后将它们传递给模板)不幸的是,我找不到如何用结果不断更新网站的解决方案。到目前为止,我看到了多个线程,这是不可能的,但真的很难相信。

第二个问题是我试图找到最快的解决方案来检查目的地。 我在堆栈上发现了一些代码,这些代码运行得非常快,但在网站上导出结果时遇到问题。在所有检查完成之前,网站正在呈现,最终网站上没有结果。第二个问题是我在向包含从数据库获取的结果的数组 serverlist 添加新值时遇到问题,我想向它们添加名为 status 的新键,它将包含检查结果(true/false 或 OK/NOK )

代码如下:

const home = require('../controllers/home');

router.get('/',
    home.main
);


exports.main = async (req, res, next) => 
    res.render('home', 
        user: 'demo',
        serverlist: await exports.serverlist()
    );
;

exports.serverlist = async (req, res) => 
    var net = require('net'), Socket = net.Socket;

    var checkPort = function(port, host, callback) 
        var socket = new Socket(), status = null;

        // Socket connection established, port is open
        socket.on('connect', function() status = 'open';socket.end(););
        socket.setTimeout(1500);// If no response, assume port is not listening
        socket.on('timeout', function() status = 'closed';socket.destroy(););
        socket.on('error', function(exception) status = 'closed';);
        socket.on('close', function(exception) callback(null, status,host,port););

        socket.connect(port, host);
    ;

    let serverlist = await home.serverlist();
    console.log(serverlist);
    for(let i=0; i < serverlist.recordset.length; i++)
        checkPort(serverlist.recordset[i].port, serverlist.recordset[i].hostname, function(error, status, host, port)
            if(status == "open")
                console.log("Reader found: ", host, port, status);
             else 
                console.log("Port closed: ", host, port, status);
            
        );
    

    console.table(serverlist.recordset);
    return serverlist;
;

我尝试在这里添加代码:

let serverlist = await home.serverlist();
        console.log(serverlist);
        for(let i=0; i < serverlist.recordset.length; i++)
            checkPort(serverlist.recordset[i].port, serverlist.recordset[i].hostname, function(error, status, host, port)
                **serverlist.recordset[i].status = status;**
                if(status == "open")
                    console.log("Reader found: ", host, port, status);
                 else 
                    console.log("Port closed: ", host, port, status);
                
            );
        

但它不会添加到结果中。 提前感谢你们的帮助。

【问题讨论】:

多线程是可能的——在节点端你有子进程,在网站端你有WebWorker,实际上如果你可以使用异步代码,为什么你需要线程。要不断更新网站,您要么需要 keep-alive 标头,要么在网站上每隔一段时间发出请求,要么使用套接字。 您好 Zydnar,非常感谢您的快速回复,非常感谢。现在正在检查保持活动的标题。我也希望能帮助我将结果添加到数组中,为什么这可能不起作用? 使用 Keep-Alive 时不要忘记 Connection 标头,请参阅:developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive。什么返回 console.log(serverlist); 我也看不到你在这个 for 循环中获得状态的位置。 嗨 Zydnar,这是 console.log(serverlist) 的示例返回; -> 记录集:[[[对象],[对象],]],记录集:[主机名:'173.249.18.8',端口:38111,主机名:'173.249.18.8',端口:1433],输出:, rowsAffected: [10] 状态来自外部模块:var net = require('net'), Socket = net.Socket; socket.connect(端口,主机); socket.on('connect', function() status = 'open';socket.end(););正如您在第二个代码中看到的那样,我添加了保存到数组: serverlist.recordset[i].status = status;但不起作用 我读过一些关于 socket.io 的文章,我真的很喜欢这种方法。今天很可能是这个! :) 【参考方案1】:
const checkPort = async (port, host, timeout = 1000) => 
    return await isPortReachable(port, timeout: timeout, host: host);
;

exports.serverlist = async (req, res) => 
    let serverlist = await home.serverlist();
    let promises = [];

    for(let i=0; i < serverlist.recordset.length; i++)
        promises.push(home.checkPort(serverlist.recordset[i].port, serverlist.recordset[i].hostname, 1000));
    

    for(let i=0; i < serverlist.recordset.length; i++)
        serverlist.recordset[i].status = await promises[i];
    

    return await serverlist;
;

上面的代码解决了我的问题,如果有人知道质量更好的方法会很高兴听到:-) 无论如何,此时该函数不会等待循环内的响应,因此它会异步运行所有检查。

【讨论】:

以上是关于NodeJS (Express + PUG) MVC 端口检查器的主要内容,如果未能解决你的问题,请参考以下文章

PUG+Express+Jquery+bootstrap

如何使用 Jade / Pug 呈现内联 JavaScript?

设置临时变量并在pug模板中进一步重用它

我不能用express.js执行jade(pug)

Express中使用Pug写模板引擎

markdown 使用Express(和Pug)在服务器端渲染页面