Node.js 如何正确处理ZeroMQ.js中的连接超时?

Node.js 如何正确处理ZeroMQ.js中的连接超时?,node.js,zeromq,Node.js,Zeromq,考虑一个具有少量进程的Node.js应用程序: 单个主进程位于内存中,像web服务器一样工作 可以通过CLI运行并在完成后退出的系统用户命令 我想在main和CLI进程之间实现类似的功能,这似乎是一个很好的选择。我选择了6.0.0-beta.4版本: 版本6.0.0(beta版)采用了全新的API,解决了许多基本问题,建议用于新项目 使用/I能够实现我想要的:CLI进程通知主进程一些发生的事件(并可以选择接收一些数据作为响应),然后继续执行。我现在遇到的一个问题是,如果主进程关闭(不可用),

考虑一个具有少量进程的Node.js应用程序:

  • 单个主进程位于内存中,像web服务器一样工作
  • 可以通过CLI运行并在完成后退出的系统用户命令
我想在main和CLI进程之间实现类似的功能,这似乎是一个很好的选择。我选择了
6.0.0-beta.4
版本:

版本6.0.0(beta版)采用了全新的API,解决了许多基本问题,建议用于新项目

使用/I能够实现我想要的:CLI进程通知主进程一些发生的事件(并可以选择接收一些数据作为响应),然后继续执行。我现在遇到的一个问题是,如果主进程关闭(不可用),我的CLI进程将挂起。如果无法建立到套接字的连接,则仍然必须执行并退出该命令,而不通知主进程

以下是在异步方法中运行的my CLI的简化代码段:

const{Request}=require('zeromq');
异步函数notify(){
让parsedResponse;
试一试{
const message={event:'hello world'};
const socket=新请求({connectTimeout:500});
socket.connect('tcp://127.0.0.1:33332');
wait socket.send(JSON.stringify(message));
const response=wait socket.receive();
parsedResponse=JSON.parse(response.toString());
}
捕获(e){
控制台错误(e);
}
返回解析响应;
}
(异步()=>{
const response=等待通知();
如果(答复){
控制台日志(响应);
}
否则{
console.log('未收到任何内容');
}
})();
我设置了选项,但不知道如何使用它。文件规定:

设置超时connect()系统调用之前的等待时间。connect()系统调用通常需要很长时间才能返回超时错误。设置此选项允许库以更早的间隔超时调用

看一看,它不是异步的:

连接到给定远程地址的套接字并立即返回。连接将在后台异步进行

好的,套接字的
send
方法可能会等待连接建立,并拒绝连接超时时的承诺……但那个里什么也并没有发生<代码>发送方法被执行,代码在解析时被卡住
接收
。它正在等待永远不会到来的主进程的答复。因此,主要问题是:<强>“如何使用<代码> CONTIONTIMEOUT//COD>选项来处理套接字的连接超时?”我发现了类似C++的问题,但实际上它没有回答问题(或者我不理解)。我不相信这个选项是无用的,它被添加到API中是为了让任何人都不能使用它

我也会很高兴找到一种解决方法,并找到一个选择。将套接字创建更改为

const socket = new Request({ receiveTimeout: 500 });
导致
receive
方法中的拒绝和以下输出:

{ [Error: Socket temporarily unavailable] errno: 11, code: 'EAGAIN' }
Nothing is received.
已执行源代码,但在本例中进程不退出。似乎有些资源很忙,没有释放。当主进程在线时,一切正常,进程退出,我在输出中得到以下回复:

{ status: 'success' }
因此,另一个问题是:“如何在使用
receiveTimeout
拒绝
receive
方法时优雅地退出流程?”
。调用
process.exit()
不是这里的选项

另外,我的环境是:

  • Kubuntu 18.04.1
  • 节点10.15.0
  • ZeroMQ绑定的安装方式如下:

    纱线添加zeromq@6.0.0-beta.4——zmq共享
    

ZeroMQ将套接字连接机制与消息传递分离。正如文档所述,
connectTimeout
仅影响
connect()
系统调用的超时,而不影响发送/接收消息的超时

例如:

const zmq = require("zeromq")

async function run() {
  const socket = new zmq.Dealer({connectTimeout: 2000})
  socket.events.on("connect:retry", event => {
    console.log(new Date(), event.type)
  })

  socket.connect("tcp://example.com:12345")
}

run()

connect:retry
事件每2秒发生一次:

> node test.js
2019-11-25T13:35:53.375Z connect:retry
2019-11-25T13:35:55.536Z connect:retry
2019-11-25T13:35:57.719Z connect:retry
如果我们将
connectTimeout
更改为
200
,则您可以看到事件将更频繁地发生。超时不是影响事件之间延迟的唯一因素,但应该清楚的是,它发生得更快

> node test.js
2019-11-25T13:36:05.271Z connect:retry
2019-11-25T13:36:05.531Z connect:retry
2019-11-25T13:36:05.810Z connect:retry

希望这能澄清
connectTimeout

的效果,感谢您澄清了
connectTimeout
的含义,但是您的代码片段对我来说不起作用,因为有一些原因需要本地连接到
tcp://localhost:12345
tcp://127.0.0.1:12345
。对不起。。。一切正常!我忘记停止主进程,因此发生了
connect
事件,而不是
connect:retry
。这很有帮助!总之,我留下了一个与
receiveTimeout
相关的选项。为了优雅地处理
receiveTimeout
拒绝,应该对
Request
实例使用以下选项:
{linger:0}
{immediate:true,sendTimeout:500,receiveTimeout:500}