ZeroMQ operation throws EXC: [ Operation cannot be accomplished in current state ]
Asked Answered
G

2

7

I am trying to make a class that will be able to send data and then receive them.

Right now, it is working only for the first send/receive and with another attempt to .send() it will throw an error below.

>Traceback (most recent call last):
  File "main.py", line 31, in <module>
    zq.send(arr)
  File "D:\ITIM\video2\MQCompare\cZMQ.py", line 17, in send
    self.socketC.send(data)
  File "zmq/backend/cython/socket.pyx", line 636, in zmq.backend.cython.socket.S
ocket.send (zmq\backend\cython\socket.c:7305)
  File "zmq/backend/cython/socket.pyx", line 683, in zmq.backend.cython.socket.S
ocket.send (zmq\backend\cython\socket.c:7048)
  File "zmq/backend/cython/socket.pyx", line 206, in zmq.backend.cython.socket._
send_copy (zmq\backend\cython\socket.c:3032)
  File "zmq/backend/cython/socket.pyx", line 201, in zmq.backend.cython.socket._
send_copy (zmq\backend\cython\socket.c:2920)
  File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc.
_check_rc (zmq\backend\cython\socket.c:10014)
    raise ZMQError(errno)
zmq.error.ZMQError: Operation cannot be accomplished in current state`

The code I'm using looks like this:

import zmq

class ZeroMQ:

def __init__(self):
    self.context = zmq.Context()
    self.socketS = self.context.socket(zmq.REP)
    self.socketS.bind("tcp://*:5555")
    self.socketC = self.context.socket(zmq.REQ)
    self.socketC.connect("tcp://localhost:5555")

def __exit__(self, exc_type, exc_value, traceback):
    self.socketC.close()
    self.socketS.close()

def send(self, data):
    self.socketC.send(data)

def recv(self):    
    self.socketS.recv()

Am I making the connection right?

Why is the function send throwing an error?

I will appreciate any help. Thank you.

Godgiven answered 1/3, 2018 at 18:43 Comment(0)
P
20

Simply because the socketC, being the instance of a REQ archetype, cannot ever send another message ( as was coded inside the implementation of the .send() class-method above ), without a prior call to socketC.recv() instance-method.

Both REQ and REP archetypes are well documented to have to obey a two-step dance of .send()-.recv()-.send()-.recv()-... resp. .recv()-.send()-.recv()-... using their native instance-methods.

This is how the ZeroMQ REQ / REP sockets were designed and documented.

Polyphonic answered 1/3, 2018 at 19:5 Comment(1)
Thank you very much. You explained it brilliantly!Godgiven
U
0

if your messaging is unidirectional, consider to using ZMQ_PUSH / ZMQ_PULL pair instead.

Unearthly answered 3/11, 2020 at 8:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.