Reputation: 371
I'm trying to get a PUB-SUB communication in ZeroMQ working where the PUB is in C++ and the SUB in python. I am using python 3.8, ZeroMQ 4.3.2, pyzmq 18.1.1 and cppzmq 4.5.0
The PUB :
int main()
{
Sleep(10000);
zmq::context_t context(1);
zmq::socket_t publisher(context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
int zipcode, temperature, relhumidity;
while (true) {
// Get values (first supposed to be random)
zipcode = 10001;
temperature = 27;
relhumidity = 61;
// Send message to the subscriber
zmq::message_t message(20);
snprintf((char *)message.data(), 20, "%05d %d %d", zipcode, temperature, relhumidity);
publisher.send(message, zmq::send_flags::none);
std::fprintf(stderr, "[INFO] Sent data: %i, %i, %i \n", zipcode, temperature, relhumidity);
if (fValue && j >= fValue) {
break;
}
j++;
}
}
The SUB :
import sys
import zmq
# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
# Subscribe to zipcode, default is NYC, 10001
zip_filter = "10001"
# Python 2 - ascii bytes to unicode str
if isinstance(zip_filter, bytes):
zip_filter = zip_filter.decode('ascii')
socket.setsockopt_string(zmq.SUBSCRIBE, zip_filter)
# Process 5 updates
for update_nbr in range(3):
string = socket.recv_string()
zipcode, temperature, relhumidity = string.split()
print("Received data : %s , %d , %d" % (zip_filter, temperature, relhumidity))
But I can't get it to work as the SUB wait for ever on string = socket.recv_string()
whereas the PUB sends messages without errors. Indeed, it returns the length of the sent messages.
Notes :
none
:Err = socket.connect("tcp://localhost:5556")
print(Err)
I am new to ZeroMQ and I don't really know where to start to solve this. Any idea ?
Upvotes: 2
Views: 2866
Reputation: 371
Thanks to all of you for the answers. I turns out that it was a classic "slow joiner" problem. I moved the Sleep(10) right before the loop to see what happens and it worked.
What was unclear on my first message (because a over cleaned my code to make it clear here) is that fValue is either set to a number to have a definite number of interation over the loop, or to 0 to loop infinitly. So, I set it to 3 just to sent few messages, but the PUB had not enough time to connect to the SUB so that the SUB see messages.
Upvotes: 0
Reputation: 121
I don't have a quick way to check your work, but I can give you some basic hints that may allow you to solve the problem.
I suggest you to start removing the filter on the receiver side. To do this you have to replace your setsockopt
with something like socket.setsockopt_string(zmq.SUBSCRIBE, "")
Moreover, always on the receiver side, I would suggest you to just print what you are receiving, without doing any kind of assumption on the data, so I would replace everything with a simple print(socket.recv_string())
(or even just print(socket.recv())
.
Your simple (debug) receiver will be something like:
import zmq
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
socket.setsockopt_string(zmq.SUBSCRIBE, "")
data = socket.recv_string()
print(data)
In this way, you realize what (and if something) is really sent through the socket.
If something is received but it is not what you are expecting, then you can work on the sender side. For instance, you can give a look at the ZMQ_SNDMORE
flag for the socket.send()
, which allows you to create multipart messages. (see the documentation here for how "topic filtering" works).
If you still need help, tomorrow I may give a look at it more thoroughly.
Upvotes: 0
Reputation: 1
Q : Any idea?
In case one has never worked with ZeroMQ,
one may here enjoy to first look at "ZeroMQ Principles in less than Five Seconds" before diving into further details
Step -1: repair your c++ side code , so as to properly define both the j
and the fValue
and verify its proper usage in the break
-condition, so as to avoid an immediate break
-out from the sending loop.
Step 0: on python side, set the ZeroMQ SUB
to subscribe first to any topic, using ""
-as the string for the explicit setup for the topic filter. If that works: your problem is isolated to a correct topic-setup for actually doing the topic-filtering. If not: you seem to also have a Line-of-Sight "visibility" problem ( which may happen when not being on the same localhost
(yes, this also sometimes happens here) ).
Upvotes: 1