I am new to ZMQ but fairly experienced with TCP , UDP, network streams in LabVIEW. I'm looking at the trivial request/reply example. So from what I see you just open the socket, do your work in a loop, and then kill the socket when terminating the loop and shutting down
My question is, what do you do about error handling? If I was using TCP, I would have a little state machine in the loop, with 3 states:
listen : uses TCP Listen and waits with timeout for incoming connections. Return to TCP listen if no connections, otherwise transition to "receive" state
receive: reads data off the TCP port with timeout. or no data If there is an error, goto state "handle error" otherwise stay in receive. Assumes a heartbeat message of somekind is coming thorugh.
handle error: cleans up the socket reference and opens a new one. Goes to "listen state"
This kind of pattern has worked fine for me in the past, allowing disconnections, reconnections without problems. So for ZMQ, if I get an error on my receive function, do I need to kill the socket and reopen one like with TCP? Or is that handled "behind the scenes"?
Regards,
Mark Garnett
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Mark,
To (over)simplify, ZMQ handles all that in the background. It is a bit hard to get your head around if you're used to TCP because most of it comes from the framework of many-to-many network topology, so I'd recommend reading the "guide" for details. To summarize the main differences as I see them
Connect/disconnect is handled in the background; this is hidden from the application (although "socket_monitor" exists if you need to know about it)
Bind and Listen return immediately, even if no connection has occurred (yet)
Messages are queued internally for when connection is made or reestablished (see "HWM")
The only errors you should expect from receive are "timeout" or "terminate" (or maybe EFSM if you're using a strict protocol)
If you're interested in reliable point-to-point connections, look into the "pirate patterns". I included an example as part of the package.
In some sense ZMQ is overkill for point-to-point, but it is directly extensible for more general message processing in a way that becomes complicated when using TCP directly. PUB/SUB is a popular and simple such use, brokering/balancing is a more complex one.
Cheers,
Martijn
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, this is referred to as the "high water mark" in the documentation. You should be able to use zmq_setsockopt to set ZMQ_RCVHWM and/or ZMQ_SNDHWM to 1. This must be done on the socket after creation but before connect/bind.
Looks like there's a new option called ZMQ_CONFLATE but it seems that interacts badly with multipart messages so it's probably not preferable.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi all,
I am new to ZMQ but fairly experienced with TCP , UDP, network streams in LabVIEW. I'm looking at the trivial request/reply example. So from what I see you just open the socket, do your work in a loop, and then kill the socket when terminating the loop and shutting down
My question is, what do you do about error handling? If I was using TCP, I would have a little state machine in the loop, with 3 states:
listen : uses TCP Listen and waits with timeout for incoming connections. Return to TCP listen if no connections, otherwise transition to "receive" state
receive: reads data off the TCP port with timeout. or no data If there is an error, goto state "handle error" otherwise stay in receive. Assumes a heartbeat message of somekind is coming thorugh.
handle error: cleans up the socket reference and opens a new one. Goes to "listen state"
This kind of pattern has worked fine for me in the past, allowing disconnections, reconnections without problems. So for ZMQ, if I get an error on my receive function, do I need to kill the socket and reopen one like with TCP? Or is that handled "behind the scenes"?
Regards,
Mark Garnett
Hi Mark,
To (over)simplify, ZMQ handles all that in the background. It is a bit hard to get your head around if you're used to TCP because most of it comes from the framework of many-to-many network topology, so I'd recommend reading the "guide" for details. To summarize the main differences as I see them
If you're interested in reliable point-to-point connections, look into the "pirate patterns". I included an example as part of the package.
In some sense ZMQ is overkill for point-to-point, but it is directly extensible for more general message processing in a way that becomes complicated when using TCP directly. PUB/SUB is a popular and simple such use, brokering/balancing is a more complex one.
Cheers,
Martijn
Thank you Martijn, this is good. I have not dived deeply into the guide yet. Is there a way to disable buffering or set the max buffer size?
Yes, this is referred to as the "high water mark" in the documentation. You should be able to use zmq_setsockopt to set ZMQ_RCVHWM and/or ZMQ_SNDHWM to 1. This must be done on the socket after creation but before connect/bind.
Looks like there's a new option called ZMQ_CONFLATE but it seems that interacts badly with multipart messages so it's probably not preferable.