Reputation: 99960
I am not sure I understand fundamentally how ZMQ (or any message queue) knows how to communicate between two servers that otherwise don't know anything about each other.
For example, using the request/reply pattern:
the requester will bind to a host and port like so:
var requester = zmq.socket("req");
requester.bind('tcp://*:5555'), function (err) {
callback(err);
});
in another node.js process on another server, I use the connect function:
var replier = zmq.socket('rep');
replier.connect('tcp://127.0.0.1:5555', function (err) {
callback(err);
});
But what I don't understand is how the requester knows where to send the message if the replier is in a different process on a totally different server pretty much anywhere?
Upvotes: 0
Views: 5185
Reputation: 13766
You already figured out one issue in the comments - connect()
is synchronous, and you attempted to use it asynchronously.
I would suggest, in node.js, that you both bind()
and connect()
synchronously, you get little benefit from running this one-time start-up action asynchronously, and it just makes the code clearer to do it synchronously. If you're building up and tearing down sockets mid-process, and you honestly have good reason to do so, then you can ignore this advice, but node gives you good reason to do this only once and use the same sockets for the lifetime of the process.
As for how two different servers can find each other, your example will fail:
// 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');
... and on the other machine...
// 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');
So, you must either reverse the bind()
and connect()
, and then change your requester
, as in the following:
// change 111.222.33.44 to the IP address or DNS name of your other machine
requester.connect('tcp://111.222.33.44:5555');
... and on the other machine...
replier.bindSync('tcp://*:5555');
... or, change your connect()
call to specify the IP address of the first machine, rather than the loopback address.
What follows is an evaluation of which side you should connect()
or bind()
on, since I feel the other advice is not complete.
It doesn't matter which side you bind()
or connect()
on, so long as you bind()
on the persistent side (your "server") and connect()
on the transient side (your "client"). If they are equally persistent, then the next way to choose is to bind()
on the side that "owns" the data, the way a server does, and connect()
on the side that "wants" the data, the way a client does.
This is why, traditionally, you'll bind()
the REP
socket and connect()
the REQ
socket, as the REQ
socket "wants" the data it is requesting, and the REP
socket "owns" the data its sending back. Similarly, you'll bind()
a PUB
socket, since it "owns" the data it's publishing, and you'll connect()
a SUB
socket, since it "wants" the data it's subscribed to.
This is all just a rule of thumb, it's perfectly possible for a SUB
socket to be more persistent than it's companion PUB
socket, or for a REQ
socket to "own" the data it's sending to the REP
socket. And in many cases, you can choose either side with zero consequences anyway, but these are useful rules to follow to have some clarity about what's going on.
Upvotes: 3
Reputation: 49075
I think you are confused with which is the requester and which is the reply-er. Or more appropriately which one is the client and which one is the server.
The Server is the bind aka socket.bind('tcp://*:5555')
. There is nothing magical about this. That asterisk does not mean multicast or discover servers on some network. It means bind aka listen on all network devices for the machine.
The client is your probably misnamed reply.connect('tcp://127.0.0.1:5555 ...
.
The client knows where the server just like in HTTP. (Hint its on the same machine :)).
ZeroMQ is very simple. It is not even really a message queue. It does not have auto discovery or a central broker so you have to do the book keeping of which is the server and client yourself (e.g. Major Domo pattern).
Upvotes: 1