aio-libs/aiozmq

ZMQ timeout error

tflorac opened this issue · 5 comments

Hi,
I'm currently trying to include a ZeroMQ service into a Pyramid application (run through Gunicorn using an async worker from aiopyramid package).
The server is started like this:

def init_zmq_handler(settings):
    server = yield from serve_pubsub(MessageHandler(),
                                     bind='tcp://0.0.0.0:5580')
    return server

A client is trying to connect from another server, using a classic synchronous application:

def zmq_response(socket, flags=zmq.POLLIN, timeout=10):
    """Get response from given socket"""
    poller = zmq.Poller()
    poller.register(socket, flags)
    if poller.poll(timeout * 1000):
        return socket.recv_json()
    else:
        return [503, "Connection timeout"]

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect('tcp://172.23.129.240:5580')
socket.send_string("ZeroMQ message!")
response = zmq_response(socket)
print("Result : {0}".format(response))

Actually, I always get a connection timeout.
The same client code works on another ZMQ server, not using "aiozmq" package...
I've checked and port 5580 is waiting for connections ("netstat -lp").

Any idea?

Best regards,
Thierry

Hi,
You are using serve_pubsub function which is wrong: it needs a topic to subscribe to and
client must send special messages (consisting of topic and message itself).

OK... :-/
Could you give me any advise about how to handle my use case which is deadly simple (a basic request/response would be sufficient, but I didn't make it work in the asynchronous way)...

Thanks,
Thierry

This first example should work for you.
You should create router on the server side.

If you want to use aiozmq.rpc.* functions you'll have to implement aiozmq rpc protocol on synchronous side as its not just raw bytes being send, aiozmq.rpc adds some meta info to data packets

I tried to make a very quick test...
On the server side, the router seems OK ; I defined a simple message handler function (via stream.transport._protocol.msg_received) which just prints the message and responds "OK" and it seems to be OK.
But on the "client" side :

  • when I call "socket.send_string('my message')", the message is displayed correctly by the router. But what is the "good" way to define a message handler for the stream?
  • how can I send a response from the router? Actually calling "socket.recv()" on the client side just hang! :-/

Thanks for any help,
Thierry

Ok, I've just added sync/async client and server example, hopefully it will help you.
It is pretty simple and dummy (no error checks, no polling etc),
but it show how sync and async can be used.