javascript – Node.js的socket.send()函数在退出之前无法完成

在我编写的一些Node.js脚本中,我注意到即使最后一行是同步调用,有时在Node.js退出之前还没有完成。

我没有看到一个console.log语句在退出之前无法运行/完成,但是我已经看到一些其他语句在退出之前无法完成,我相信它们都是同步的。在这种情况下,我可以看到为什么异步函数的回调当然不会被触发。

所涉及的代码是ZeroMQ .send()调用,如下所示:

   var zmq = require('zmq');
   var pub = zmq.socket('pub');

   pub.bindSync('tcp://127.0.0.1:5555');   

    setInterval(function(){
        pub.send('polyglot');
    },500);

以上代码按预期方式工作,但如果我删除了setInterval()并且像下面这样调用:

   var zmq = require('zmq');
   var pub = zmq.socket('pub');

    pub.bindSync('tcp://127.0.0.1:5555');

    pub.send('polyglot');  //this message does not get delivered before exit
    process.exit(0);

…然后消息将不会被传递 – 程序将显然在pub.send()调用完成之前退出。

在Node.js中退出之前,确保语句完成的最佳方法是什么?关机挂钩将在这里工作,但我恐怕只是掩盖了问题,因为你不能把所有你需要的,以确保运行在一个关闭挂钩。

这个问题也可以这样说明:

 if (typeof messageHandler[nameOfHandlerFunction] == 'function') {
          reply.send('Success');
          messageHandler[nameOfHandlerFunction](null, args);
         } else {
         reply.send('Failure'); //***this call might not complete before the error is thrown below.***
         throw new Error('SmartConnect error: no handler for ZMQ message sent from Redis CSV uploader.');
     }

我相信这是一个合法/严重的问题,因为很多程序只需要发布消息,然后死机,但是我们如何有效地确保所有的消息被发送(尽管不一定被接收)?

编辑:
解决这个问题的一个(潜在的)方法是:

socket.send('xyz');
socket.close(); // supposedly this will block until the above message is sent
process.exit(0);
潜入zeromq.node,你可以看到Socket.send只是pushes your data to _outgoing

this._outgoing.push([msg, flags]);

…然后calls _flush iff zmq.ZMQ_SNDMORE is unset

this._flush();

看起来像_flush is actually doing the socket write.如果_flush()失败,it emits an error

编辑:

我猜想在退出之前调用pub.unbind(),会强制调用_flush():

pub.unbind('tcp://127.0.0.1:5555', function(err) {
  if (err) console.log(err);
  process.exit(0); // Probably not even needed
});
http://stackoverflow.com/questions/29906637/node-js-socket-send-functions-failing-to-complete-before-exit

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:javascript – Node.js的socket.send()函数在退出之前无法完成