PYZMQ REQREP多个客户端ZMQError,带轮询

2024-04-19 09:00:12 发布

您现在位置:Python中文网/ 问答频道 /正文

对于一个REQ-REP模式,我试图使用poll请求多个具有超时的clients,这样如果server检测到它无法从第一个client接收消息,它将超时并继续到下一个client。在

但在初始超时之后,它似乎无法将下一条消息发送到第二条client。在

我在server中的zmq.error.ZMQError: Operation cannot be accomplished in current state这行socket.send_string("Sensor Data")上得到这个错误。在

全输出

Connecting to machine...
Successfully connected to machine 127.0.0.1:9999
Successfully connected to machine 127.0.0.1:9998
Sending request  0 ...
Machine did not respond
Sending request  1 ...
Traceback (most recent call last):
  File "C:\Users\tobiw\Documents\Python\Raspberry Pi\zmq\REQrep\testSIMPLEpoll.py", line 16, in <module>
    socket.send_string("Sensor Data")
  File "C:\Users\tobiw\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyzmq-17.0.0b3-py3.6-win32.egg\zmq\sugar\socket.py", line 541, in send_string
    return self.send(u.encode(encoding), flags=flags, copy=copy, **kwargs)
  File "C:\Users\tobiw\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pyzmq-17.0.0b3-py3.6-win32.egg\zmq\sugar\socket.py", line 384, in send
    return super(Socket, self).send(data, flags=flags, copy=copy, track=track)
  File "zmq/backend/cython/socket.pyx", line 727, in zmq.backend.cython.socket.Socket.send
  File "zmq/backend/cython/socket.pyx", line 771, in zmq.backend.cython.socket.Socket.send
  File "zmq/backend/cython/socket.pyx", line 249, in zmq.backend.cython.socket._send_copy
  File "zmq/backend/cython/socket.pyx", line 244, in zmq.backend.cython.socket._send_copy
  File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc
    raise ZMQError(errno)
zmq.error.ZMQError: Operation cannot be accomplished in current state
[Finished in 5.3s with exit code 1]

服务器

^{pr2}$

客户

import zmq
import time
import json

port = "9998" # multiple similar clients but just with different ports

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:%s" % port)

while True:
    #  Wait for next request from server
    message = str(socket.recv(), "utf-8")
    print("Received request: ", message)
    time.sleep(1)
    msgDict = {
        'sensor': "6",
        'data': "123456789",
        'client': "9876",
    }
    msg_json = json.dumps(msgDict)
    socket.send_string(msg_json)

如果server能够接收来自第一个client的消息,那么第二个send到第二个client将正常工作,但是如果{}无法从第一个client接收消息,那么错误就会重现。在


Tags: inclientsendbackend消息stringserverrequest
1条回答
网友
1楼 · 发布于 2024-04-19 09:00:12

最重要的是,REQ-REP模式中的zmq.error.ZMQError: Operation cannot be accomplished in current state表示{}的顺序不正确。在我的例子中,由于在for-loop中对receive进行轮询,REQ server端没有最终的recv,因为它超时了。当方法循环返回时,它再次转到send,结果是{}。非法的双send方案。在

我做了什么来纠正它: 我从REQ-REP模式切换到经销商代表模式。这为我提供了一个异步服务器,可以与多个REP客户机进行通信。在

client保持不变的情况下,对于感兴趣的人来说,这是一个新的server

服务器

import zmq
import json

ports = ["127.0.0.1:9999", "127.0.0.1:9998"]

context = zmq.Context()
print("Connecting to machine...")
socket = context.socket(zmq.DEALER)
socket.setsockopt(zmq.LINGER, 0)
for port in ports:
    socket.connect("tcp://%s" % port)
    print("Successfully connected to machine %s" % port)

for request in range(len(ports)):
    print("Sending request ", request, "...")
    socket.send_string("", zmq.SNDMORE)  # delimiter
    socket.send_string("Sensor Data")  # actual message

    # use poll for timeouts:
    poller = zmq.Poller()
    poller.register(socket, zmq.POLLIN)

    socks = dict(poller.poll(5 * 1000))

    if socket in socks:
        try:
            socket.recv()  # discard delimiter
            msg_json = socket.recv()  # actual message
            sens = json.loads(msg_json)
            response = "Sensor: %s :: Data: %s :: Client: %s" % (sens['sensor'], sens['data'], sens['client'])
            print("Received reply ", request, "[", response, "]")
        except IOError:
            print("Could not connect to machine")
    else:
        print("Machine did not respond")

相关问题 更多 >