2014-01-04 3 views
2

Я пытаюсь разработать брокера, который служит прокси для связи между некоторыми работниками и клиентами с использованием 0MQ. Задача была относительно простой, чтобы обойтись без обещаний, но из-за того, что я неопытен с использованием обещаний, я не могу понять, как реализовать обещания в этом примере.Посылы в связи с брокер-клиентом с использованием 0MQ

Код для Брокера:

//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"); 

... 

Клиент подключается к брокеру, отправляет сообщение, но сообщение не обрабатывается брокером. Любые идеи относительно того, что я делаю неправильно? Любая помощь будет оценена по достоинству.

ответ

3

Я не работал с ZeroMQ, но from the docs Я предполагаю, что on, по-видимому, является механизмом подписки на события, а не асинхронной операцией в режиме NodeJS, принимающей обратный вызов. Он может стрелять не один раз, верно?

Если это так, почему вы хотите использовать обещания вообще? Они кажутся неправильной абстракцией для этой конкретной ситуации.

Обещания представляют собой операции, которые заканчиваются или завершаются один раз, а не асинхронные потоки значений.

Даже если

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

работал, не было бы никакой пользы для вас, потому что then будет вызываться только один раз.
Я предполагаю, что это не то, что вы хотели.

Если вы ищете способ фильтрации, сопоставления, слияния или дросселирования асинхронных последовательностей, вы можете посмотреть в RxJS, который делает именно это (он также взаимодействует с обещаниями). Но обещания не должны и не могут использоваться в качестве замены событий, которые срабатывают более одного раза.


С другой стороны, если сообщение действительно приходит только один раз, я согласен, что лучше использовать обещание абстрагировать его. Однако nfbind или nbind не будет работать здесь, потому что они требуют 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(); 
+0

Отсюда 'Q.nbind (frontend.on, внешний интерфейс);'? Каждое событие является обещанием его ценности. –

+0

@Benjamin: Что именно вы имеете в виду? Обещание может закончиться только один раз, но обработчик никуда не денется, поэтому zeromq попытается вызвать обработчик безрезультатно. Конечно, вы можете создать обещание для каждого сообщения, но я не думаю, что это то, чего хочет OP. * Кроме того, zeromq 'on' is * not * функция NodeJS-стиля: его обратная связь является' function (message) ', а не' function (err, result) '. Таким образом, любое обещание потерпит неудачу. –

+0

А, если это так в zeromq, вы можете уточнить это в своем ответе. Благодарю. –