I'm using the pattern: Router-Dealer
Router send messages to Dealer(A) all the time.
Dealer just receive message (SOCKOPT_IDENTITY: A).
Work fine in this time.
Then
i press Ctrl-C to stop the Dealer , and reconnect.
Now i got nothing ~~
Is there anything wrong?
How can i fix it?
Thanks.
You are using the wrong kind of sockets and/or direction of messages.
I would be easier to understand what you would like to do if you write what you are using the socket for.
Assuming that you want to use Dealer and Router sockets then you should send the message in the other direction (Dealer => Router).
The Router socket connects many inputs to a single output or a single input to many outputs. This is done by adding/removing an identifier to the message, that describes where it came from or where it should go.
So in your case when you are trying to send a message from the router, the router socket will try to remove the identifier from the message, so that it can understand which connection it should forward the message on. So if you really want this then you need to associate your dealer connection with an identifier and then add that to the message that your sending through the router.
But I'm pretty sure that you actually want to use another combination of zmq sockets.
Related
I have several dealers connecting to one Router socket. The dealers send data asynchronously and the Router gathers/processes the data.
What I need to do is find a way to know when a dealer has stopped sending data/disconnected from the router socket.
I build a map of all the connection identities.
I have a monitor connected the the router port and I receive notifications for connects/disconnects.
The problem is I can't find a way to identify which dealer the monitor notifications are for. The notifications only give me a FD which is of little use.
Is there a way to map between notifications and connection IDs?
If not mistaken, the zeroMq allows you to determine only the fact of connection/disconnection.
In my opinion, a good solution would be something like this: when the notification is received, ROUTER must send to all connected dealers a heartbeat message with a timeout and the one who did not respond - disconnected.
I'm trying to implement the basic DEALER - ROUTER socket in ZeroMQ.
My Question has multiple parts.
Before that, here are my sample scripts
DEALER SCRIPT
ROUTER SCRIPT
QUESTION -
Firstly,The vanilla DEALER SCRIPT of mine is unable to read the message from the SOCKET.
Secondly, When I'm implementing a DEALER or ROUTER PATTERN, is it mandatory to pass the IDENTITY across(as a part of header) i.e can't the message be sent without any IDENTITY.
In other words can a DEALER - ROUTER pattern (can be see below) can co-exists and pass message among themselves without sending identity info in header.
DEALER WITHOUT ANY IDENTITY
ROUTER WITHOUT ANY IDENTITY
because, I'm unable to get it working without the identity as well.
NOTE : - The Zeromq ruby library(ruby client) currently in picture is ffi-rzmq
Your code shows a lot of misunderstandings about how ZMQ works, I suggest you read the guide and follow the Ruby examples to set up your scripts.
Here's the problems that I see:
In your DEALER script, you explicitly receive the identity - it will never get its own identity as part of the message, this is silently removed by ZMQ because it's not intended to be message data, it's intended to be an "address" used by the ROUTER socket. So, you're actually receiving the delimiter into your identity variable, the message into your delimiter variable, and then nothing is left and your msg variable is empty. If you puts the values of all three variables, you'll see it.
You don't need a ZMQ poller in your DEALER socket. Pollers are intended to receive messages from multiple sockets, you're only using one socket. I don't know whether it's actually intended to work with one socket at all, but at any rate it's needless additional complexity, rip it out. See here for a simple send/receive example from the guide (if you just change the socket type to DEALER, add your "particulars" - identity, address, port, etc - and omit the send, it should work for you)
In your second example, where you don't set an identity, the ROUTER socket doesn't address the message to any connected client - you always need to send the client identity as the first frame of the message. Typically, you'll receive a message from your client, which includes its identity, and you'll use that identity to send the message back. You're only able to skip that in the first example because your script already knows the identity, "client"
Maybe I missed this in the docs, but how do you use ZeroMQ for simple signaling between multiple nodes? Something like REQ to REQ, with no REPs.
Example: I sometimes want to tell all other nodes to invalidate cache pages or notify them that something happened.
Request-reply won't work because I don't want the requester to block waiting for an empty response. I want to allow multiple signals to build up at the server.
Publish-subscribe feels wrong because I'd have to subscribe to everything, and start two sockets, one for each direction of communication.
PAIRs don't support automatically reconnecting and have other limitations.
Is pub-sub the best way to go? Or am I better just to use a traditional socket, write to both ends, and handle disconnections/reconnecting?
What you want is a dealer socket in your client side and a dealer socket on your server side. If you want to be able to send message to a specific node from the server side, then you better use a router socket in the server.
I have a single publisher application (PUB) which has N number of subscribers (SUB)
These subscribers need to be able to catch up if they are restarted, or fall down and miss messages.
We have implemented a simple event store that the publisher writes to.
We have implemented a CatchupService which can query the event store and send missed messages to the subscriber.
We have implemented in the subscriber a PUSH socket which sends a request for missed messages.
The subscriber also has a PULL socket which listens for missed messages on a seperate port.
The subscriber will:
Detect a gap
Send a request for missed messages to our CatchupService, the request also contains the address on which to send the results to.
The catchup service has a PULL socket on which it listens for requests
When the CatchupService receives a request it starts a worker thread which:
Gets the missed messages
Opens a PUSH socket connecting to the subscribers PULL socket
Sends the missed messages to the subscriber.
This seems to work quite well however we are unsure if we are using the right socket types for this sort of application. Are these correct or should be using a different pattern.
Sounds okay. Otherwise 0MQ is able to recovery from message loss when peers go offline for a short time. Take a look at the Socket Options and specifically option ZMQ_SNDHWM.
I don't know just how guaranteed the 0MQ recovery mechanisms are so maybe you're best to stay with what you've got, but it is something to be aware of.
How can a client both subscribe and listen to replies with zeromq?
That is, on the client side I'd like to run a loop which only receives messages and selectively sends requests, and on the server side I'd like to publish most of the time, but to sometimes receive requests as well.
It looks like I'll have to have two different sockets - one for each mode of communication. Is it possible to avoid that and on the server side receive "request notifications" from the socket on a zeromq callback thread while pushing messages to the socket in my own thread?
I am awfully new to ZeroMQ, so I'm not sure if what you want is considered best-practice or not. However, a solution using multiple sockets is pretty simple using zmq_poll.
The basic idea would be to have both client and server:
open a socket for pub/sub
open a socket for req/rep
multiplex sends and receives between the two sockets in a loop using zmq_poll in an infinite loop
process req/rep and pub/sub events within the loop as they occur
Using zmq_poll in this manner with multiple sockets is nice because it avoids threads altogether. The 0MQ guide has a good example here. Note that in that example, they use a timeout of -1 in zmq_poll, which causes it to block until at least one event occurs on any of the multiplexed sockets, but it's pretty common to use a timeout of x milliseconds or something if your loop needs to do some other work as well.
You can use 2 threads to handle the different sockets. The challenge is that if you need to share data between threads, you need to synchronize it in a safe way.
The alternative is to use the ZeroMQ Poller to select the sockets that have new data on them. The process would then use a single loop in the way bjlaub explained.
This could be accomplished using a variation/subset of the Majordomo Protocol. Here's the idea:
Your server will be a router socket, and your clients will be dealer sockets. Upon connecting to the server, the client needs to send some kind of subscription or "hello" message (of your design). The server receives that packet, but (being a router socket) also receives the ID of that client. When the server needs to send something to that client (through your design), it sends it to that ID. The client can send and receive at will, since it is a dealer socket.