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 端口检查器的主要内容,如果未能解决你的问题,请参考以下文章