2015-05-07 4 views
0

Я не уверен, что понимаю, как ZMQ (или любая очередь сообщений) знает, как общаться между двумя серверами, которые иначе ничего не знают друг о друге.Как работает ZMQ между двумя разными машинами

Например, используя запрос/ответ модель:

запрашивающий будет связываться с хостом и портом, как так:

var requester = zmq.socket("req"); 
requester.bind('tcp://*:5555'), function (err) { 
      callback(err); 
     }); 

в другом процессе Node.js на другом сервере, я использую подключения функции:

var replier = zmq.socket('rep'); 
    replier.connect('tcp://127.0.0.1:5555', function (err) { 
     callback(err); 
    }); 

Но то, что я не понимаю, как запрашивающая знает, куда послать сообщение, если replier находится в другом процессе на совершенно другой серв er почти везде?

+0

Вы не смешиваете запросчика и не отвечаете? глядя на ваш код, запрашивающий прослушивает и ответ отвечает – dmaij

ответ

2

Вы уже разобрались с одной проблемой в комментариях - connect() является синхронным, и вы попытались использовать его асинхронно.

Я хотел бы предложить в node.js, что вы оба: bind() и connect() синхронно, вы получаете небольшую выгоду от запуска этого одноразового запуска асинхронно, и это просто делает код более четким, чтобы сделать это синхронно. Если вы наращиваете и разрываете сокеты в середине процесса, и у вас, честно говоря, есть все основания для этого, тогда вы можете игнорировать этот совет, но узел дает вам повод сделать это только один раз и использовать те же сокеты для жизни процесса.

касается того, как два разных сервера могут найти друг друга, ваш пример не получится:

// this tells the socket to listen to all incoming connections on post 5555 
// but it does not create a connection to any other machine or process 
requester.bindSync('tcp://*:5555'); 

... и на другой машине ...

// this tells the socket to connect to a bound socket on the same machine 
// it will not find a socket on another machine 
replier.connect('tcp://127.0.0.1:5555'); 

Таким образом, вы должны либо реверсе bind() и connect(), а затем изменить requester, как в следующем примере:

// change 111.222.33.44 to the IP address or DNS name of your other machine 
requester.connect('tcp://111.222.33.44:5555'); 

... и на другой машине ...

replier.bindSync('tcp://*:5555'); 

...или, измените свой вызов connect(), чтобы указать IP-адрес первой машины, а не адрес обратной связи.

Ниже следует оценка того, с какой стороны вы должны connect() или bind(), поскольку я чувствую, что другой совет не является полным.

Это не имеет значения, с какой стороной вы bind() или connect() на, так долго, как вы bind()на постоянной стороны (ваш «сервер») и connect() на транзиторной стороны (ваш «клиент»). Если они одинаково устойчивы, то следующий способ выбрать: bind() на стороне, которая «владеет» данными, как это делает сервер, и connect() на стороне, которая «хочет» данные, как делает клиент.

Вот почему, традиционно, вы будете bind()REP гнездо и connect()REQ гнездо, как REQ гнездо «хочет» данные, которые он запрашивает, и REP гнездо «владеет» данные отправки обратно. Аналогично, вы будете bind() a PUB сокет, так как он «владеет» данными, которые он публикует, и вы будете connect() a SUB сокет, так как он «хочет» данные, на которые он подписан.

Это всего лишь правило, это вполне возможно для SUB гнездо, чтобы быть более стойким, чем это компаньон PUB гнездо, или для REQ сокета «собственные» данные, которые он посылает в REP гнездо. И во многих случаях вы можете выбрать любую сторону с нулевыми последствиями в любом случае, но это полезные правила, чтобы следовать, чтобы иметь определенную ясность в отношении того, что происходит.

+0

отличный ответ. честно говоря, я думаю, что должна быть асинхронная версия connect() ... тогда вы можете быть уверены, что другой сервис/сервер доступен –

1

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

The Server is a a aka socket.bind('tcp://*:5555'). В этом нет ничего волшебного. Эта звездочка не означает многоадресную рассылку или обнаружение серверов в какой-либо сети. Это означает, что вы можете прослушивать все сетевые устройства для устройства.

The client Возможно, вы ошибочно назвали reply.connect('tcp://127.0.0.1:5555 ....

Клиент знает, где сервер, как и HTTP. (Подскажите его на той же машине :)).

ZeroMQ очень прост. Это даже не очередь сообщений. У него нет автоматического обнаружения или центрального брокера, поэтому вам нужно вести бухгалтерский учет, который является самим сервером и клиентом (например, основной шаблон Domo).

+0

, вы приравниваете сервер к запрашивающему и репликатору с клиентом? Или наоборот? –

+0

Я переименовал сокеты для повторителя и реквестера –

+0

@AlexMills Связывание - это сервер. Вы можете четко видеть даже в официальном документе/примере кода, с которым я связан. Клиент просто подключается к серверу, который находится на локальной машине. Сервер прослушивает все сетевые устройства, включая loopback (127.0.0.1). Клиент просто подключается к loopback. –

Смежные вопросы