使用0MQ在代理 - 客户端通信中的承诺

时间:2014-01-04 22:13:04

标签: javascript node.js zeromq promise broker

我正在尝试开发一个代理,作为使用0MQ的一些工作人员和客户之间通信的代理。没有承诺,任务相对简单,但由于我对使用promises缺乏经验,我无法理解如何在这个例子中实现promises。

经纪人代码:

//Broker that serves as proxy for workers and clients
var zmq = require('zmq');
var frontend = zmq.socket('router');
var backend = zmq.socket('router');
var Q = require('q');

frontend.bindSync('tcp://*:8001');
backend.bindSync('tcp://*:8002');

var frontendOn = Q.nbind(frontend.on, frontend);
var backendOn = Q.nbind(backend.on, backend);

var requestFrontend = frontendOn('message').then(function(){
console.log("Message received");
});
var requestBackend = backendOn('message').then(responseBackend);

...

客户代码:

//Client program that communicates with broker

var zmq = require('zmq')
var requester = zmq.socket('req');
var Q = require('q');

var arguments = process.argv.splice(2);

//Connect with broker
requester.connect(arguments[0]); 

console.log("Connected successfully to broker");

//Send message to broker
requester.send(arguments[1]);   

console.log("Message sent to broker");

...

客户端连接到代理,发送消息但代理不处理消息。关于我做错了什么的任何想法?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

我没有使用过ZeroMQ,但from the docs我认为on似乎是一个事件订阅机制,而不是接受回调的NodeJS样式的异步操作。它可能不止一次发射,对吗?

如果是这种情况,为什么要使用承诺呢?对于这种特殊情况,它们似乎是错误的抽象。

Promise表示完成或失败一次的操作,而不是异步的值流。

即使

var requestFrontend = frontendOn('message').then(function(){
  console.log("Message received");
});

工作,这对你没有任何好处,因为then只会被调用一次 我认为这不是你想要的。

如果您正在寻找一种过滤,映射,合并或限制异步序列的方法,您可以查看RxJS完全相同的内容(它还与promises接口)。但承诺不应该,也不能用来代替不止一次发生的事件。


另一方面,如果消息确实只发生一次,我同意最好使用promises来抽象它。但是, nfbindnbind无法在此处,因为它们需要function(err, result)式回调,并且您有function(result)

以下是我建议您使用的内容:

function promiseOneMessage(queue) {
  var deferred = Q.defer();

  queue.on('message', deferred.resolve);
  queue.on('error', deferred.reject);

  return deferred.promise;
}

var requestFrontend = promiseOneMessage(frontend)
  .then(function (message) {
    console.log("Message received", message);
  })
  .done();

var requestBackend = promiseOneMessage(backend)
  .then(responseBackend)
  .done();