如何定期从node.js服务器轮询另一台服务器?

如何定期从node.js服务器轮询另一台服务器?,node.js,polling,Node.js,Polling,我有一个node.js服务器a,带有数据库mongodb。 还有另一个远程服务器B(不需要基于节点),它公开HTTP/GET API“/status”,并返回“FREE”或“BUSY”作为响应 当用户点击服务器a中的特定API端点时(比如POST/test),我希望每分钟开始轮询服务器B的状态API,直到服务器B返回“FREE”作为响应。用户无需等待服务器B返回“免费”响应(轮询B是服务器a中的后台作业)。一旦服务器A从B获得“免费”响应,它将向用户发送电子邮件 在服务器A中如何实现这一点,同时

我有一个node.js服务器a,带有数据库mongodb。 还有另一个远程服务器B(不需要基于节点),它公开HTTP/GET API“/status”,并返回“FREE”或“BUSY”作为响应

当用户点击服务器a中的特定API端点时(比如POST/test),我希望每分钟开始轮询服务器B的状态API,直到服务器B返回“FREE”作为响应。用户无需等待服务器B返回“免费”响应(轮询B是服务器a中的后台作业)。一旦服务器AB获得“免费”响应,它将向用户发送电子邮件

在服务器A中如何实现这一点,同时记住并发用户的数量可能会很大

我建议你使用议程。 使用agenda,您可以创建定期计划,在该计划下,您可以灵活安排任何事情

我建议您使用请求模块进行HTTP get/post请求。

从node.js文档中的示例开始,我将使用类似于这里的代码。我测试过了,它能工作。顺便说一句,我在这里假设api响应类似于
{“status”:“BUSY”}
&
{“status”:“FREE”}

您可能希望使用此脚本,并为您消除不必要的代码,但这只是一个家庭作业;)

更新:

为了处理node.js中的大量并发,我建议实现集群或使用框架。以下是开始研究该主题的一些链接:


使用诸如request、superagent或restify客户端之类的库来调用服务器B。我建议您在调用B时避免轮询,而是使用webhook(假设您也在编写B)。如果无法更改B,则可以使用setTimeout以1秒的间隔安排后续呼叫。

轮询服务器B只是一个后台进程,或者您需要用户知道返回值空闲还是忙?无论如何,请检查node.js中get请求的基本实现。@timo:轮询服务器B只是一个后台进程。一旦服务器B免费返回,我将执行一些任务,如发送电子邮件。请检查我下面的答案。您的代码回答了我问题的第一部分,
如何在服务器A中实现这一点
。我还想知道,这个简单的基于setTimeout的实现是否足以满足我问题的第二部分
,记住并发用户的数量可能会变大
?如果必须为每个请求运行此过程,您只需要实现一个集群或类似的解决方案,以便在出现问题时升级对你的服务器有很大的需求。这是一项相当复杂的任务,我建议您在线搜索解决方案。我会用几个链接更新答案。谢谢你建议的日程安排。这似乎解决了我的目的。
const http = require('http');

const poll = {
    pollB: function() {
        http.get('http://serverB/status', (res) => {
            const { statusCode } = res;

            let error;
            if (statusCode !== 200) {
                error = new Error(`Request Failed.\n` +
                    `Status Code: ${statusCode}`);
            }

            if (error) {
                console.error(error.message);
                res.resume();
            } else {
                res.setEncoding('utf8');
                let rawData = '';
                res.on('data', (chunk) => { rawData += chunk; });
                res.on('end', () => {
                    try {
                        const parsedData = JSON.parse(rawData);

                        // The important logic comes here
                        if (parsedData.status === 'BUSY') {
                            setTimeout(poll.pollB, 10000); // request again in 10 secs
                        } else {
                            // Call the background process you need to
                        }
                    } catch (e) {
                        console.error(e.message);
                    }
                });
            }
        }).on('error', (e) => {
            console.error(`Got error: ${e.message}`);
        });
    }
}

poll.pollB();