ZeroMQ - 如果服务器没有响应,如何让客户端放弃并稍后尝试?
ZeroMQ - how to make a CLIENT to give up and try at a later time if the SERVER doesn't respond?
假设我有一个非常简单的 Client/Server 模型,使用来自 ZeroMQ 的 REQ/REP
。请参阅下面的 python 代码。
在下面的代码中,客户端将永远等待,但 我希望客户端放弃(假设 20 秒后)并在没有得到响应的情况下继续其生命。 服务器可能已关闭,路由器已拔下插头,WiFi 无法正常工作。我真的不关心或者应该关心为什么。
稍后,我会让客户再试一次,这可能是一个完全不同的请求。
但我担心我会越过一个旧的请求,把事情弄乱,导致更多问题。
有谁知道如何优雅地做到这一点?我一直在绞尽脑汁寻找一个简单的解决方案。
简单的客户端代码
#!/usr/bin/env python3
import zmq
from time import sleep
# CREATE SOCKET - Client (USING zmq.REQ)
my_client_context = zmq.Context()
my_client_socket = my_client_context.socket(zmq.REQ)
my_client_socket.connect('tcp://127.0.0.1:5557')
# [REQ]uest AND [REP]ly
to_server = b"Hi"
my_client_socket.send(to_server)
from_server = my_client_socket.recv()
print(from_server)
sleep(2)
# REQuest AND REPort
to_server = b"blah"
my_client_socket.send(to_server)
from_server = my_client_socket.recv()
print(from_server)
简单的服务器代码
#!/usr/bin/env python3
import zmq
# CREATE SOCKET - Server (USING zmq.REP)
my_server_context = zmq.Context()
my_server_socket = my_server_context.socket(zmq.REP)
my_server_socket.bind('tcp://127.0.0.1:5557')
# LISTEN ON SOCKET
while True:
msg = my_server_socket.recv()
if msg == b'Hi':
to_client = b"Well hello to you"
my_server_socket.send(to_client)
else:
to_client = b"Not sure what you want"
my_server_socket.send(to_client)
ZeroMQ支持.poll()
到.recv()
之前的非阻塞测试
可以使用.poll()
.poll( timeout = None, flags = zmq.POLLIN ) # poll the socket for events
The default is to poll forever for incoming events. Timeout is in milliseconds, if specified.
Parameters:
timeout
: int
[default: None
]
The timeout ( in milliseconds ) to wait for an event. If unspecified (or specified None
), will wait forever for an event.
flags
: bitfield (int
) [default: POLLIN
]
The event flags to poll for ( any combination of POLLIN | POLLOUT
). The default is to check for incoming events ( POLLIN
).
Returns:
events
: bitfield (int
)
The events that are ready and waiting. Will be 0 if no events were ready by the time timeout was reached.
ZeroMQ 支持 .recv()
的非阻塞、异步模式
因此可以构建自己的、非阻塞的、软 RT 调整的 .recv()
忙循环。
while not_SIG_KILL_yet: # main-<LOOP> -<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-
try: # TRY: an-outer-most-<ExceptionWRAPPER> for KeyboardInterrupt
''' ............................................................ 250 msec sample-rate <loop>-task ____________________________________________________________________________'''
try:
maybeRECV = my_client_socket.recv( zmq.NOBLOCK )
# Handle .recv() data
except:
# Handle ZMQError EAGAIN
# .INC failed attempts COUNTER
# .IF >
if ( COUNTER > aTresholdToGiveUp ):
not_SIG_KILL_yet = False
continue
# GIVE CPU-a-NAP -------------------- may be segmented + EXC-handler
# ------------------------------------------------------------------
except KeyboardInterrupt:
not_SIG_KILL_yet = False
pass
# <EoW>-----------------# main-<LOOP> -<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-
ZeroMQ 适用于 Archetype 模式,而不适用于 "dumb"-socket
于是害怕遇见"old"-[REP
]-答(还是挂(和它必须挂在那里,不是吗?)在内部队列的服务器端) 是正确的 因为 REQ/REP
-模式正是按照定义进行的。
CLIENT端有权优雅地关闭关联资源,并向SERVER发送清除马戏团的指示。
ZeroMQ 支持非常动态的 set-up/tear-downs 基础元素,并且不让通信对方(在本例中为 SERVER)对通信对等方打算做什么有任何疑问是一种公平的方式。
阅读有关以下内容的详细信息:
my_client_context.setsockopt( zmq.LINGER, 0 ) # do not wait for anything
my_client_socket.close() # statefull close
my_client_context.term() # graceful termination / release of resources ( no MEM leaks )
假设我有一个非常简单的 Client/Server 模型,使用来自 ZeroMQ 的 REQ/REP
。请参阅下面的 python 代码。
在下面的代码中,客户端将永远等待,但 我希望客户端放弃(假设 20 秒后)并在没有得到响应的情况下继续其生命。 服务器可能已关闭,路由器已拔下插头,WiFi 无法正常工作。我真的不关心或者应该关心为什么。
稍后,我会让客户再试一次,这可能是一个完全不同的请求。
但我担心我会越过一个旧的请求,把事情弄乱,导致更多问题。
有谁知道如何优雅地做到这一点?我一直在绞尽脑汁寻找一个简单的解决方案。
简单的客户端代码
#!/usr/bin/env python3
import zmq
from time import sleep
# CREATE SOCKET - Client (USING zmq.REQ)
my_client_context = zmq.Context()
my_client_socket = my_client_context.socket(zmq.REQ)
my_client_socket.connect('tcp://127.0.0.1:5557')
# [REQ]uest AND [REP]ly
to_server = b"Hi"
my_client_socket.send(to_server)
from_server = my_client_socket.recv()
print(from_server)
sleep(2)
# REQuest AND REPort
to_server = b"blah"
my_client_socket.send(to_server)
from_server = my_client_socket.recv()
print(from_server)
简单的服务器代码
#!/usr/bin/env python3
import zmq
# CREATE SOCKET - Server (USING zmq.REP)
my_server_context = zmq.Context()
my_server_socket = my_server_context.socket(zmq.REP)
my_server_socket.bind('tcp://127.0.0.1:5557')
# LISTEN ON SOCKET
while True:
msg = my_server_socket.recv()
if msg == b'Hi':
to_client = b"Well hello to you"
my_server_socket.send(to_client)
else:
to_client = b"Not sure what you want"
my_server_socket.send(to_client)
ZeroMQ支持.poll()
到.recv()
之前的非阻塞测试
可以使用.poll()
.poll( timeout = None, flags = zmq.POLLIN ) # poll the socket for events
The default is to poll forever for incoming events. Timeout is in milliseconds, if specified.
Parameters:
timeout
:int
[default:None
]The timeout ( in milliseconds ) to wait for an event. If unspecified (or specified
None
), will wait forever for an event.
flags
: bitfield (int
) [default:POLLIN
]The event flags to poll for ( any combination of
POLLIN | POLLOUT
). The default is to check for incoming events (POLLIN
).Returns:
events
: bitfield (int
)The events that are ready and waiting. Will be 0 if no events were ready by the time timeout was reached.
ZeroMQ 支持 .recv()
的非阻塞、异步模式
因此可以构建自己的、非阻塞的、软 RT 调整的 .recv()
忙循环。
while not_SIG_KILL_yet: # main-<LOOP> -<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-
try: # TRY: an-outer-most-<ExceptionWRAPPER> for KeyboardInterrupt
''' ............................................................ 250 msec sample-rate <loop>-task ____________________________________________________________________________'''
try:
maybeRECV = my_client_socket.recv( zmq.NOBLOCK )
# Handle .recv() data
except:
# Handle ZMQError EAGAIN
# .INC failed attempts COUNTER
# .IF >
if ( COUNTER > aTresholdToGiveUp ):
not_SIG_KILL_yet = False
continue
# GIVE CPU-a-NAP -------------------- may be segmented + EXC-handler
# ------------------------------------------------------------------
except KeyboardInterrupt:
not_SIG_KILL_yet = False
pass
# <EoW>-----------------# main-<LOOP> -<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-<o>-
ZeroMQ 适用于 Archetype 模式,而不适用于 "dumb"-socket
于是害怕遇见"old"-[REP
]-答(还是挂(和它必须挂在那里,不是吗?)在内部队列的服务器端) 是正确的 因为 REQ/REP
-模式正是按照定义进行的。
CLIENT端有权优雅地关闭关联资源,并向SERVER发送清除马戏团的指示。
ZeroMQ 支持非常动态的 set-up/tear-downs 基础元素,并且不让通信对方(在本例中为 SERVER)对通信对等方打算做什么有任何疑问是一种公平的方式。
阅读有关以下内容的详细信息:
my_client_context.setsockopt( zmq.LINGER, 0 ) # do not wait for anything
my_client_socket.close() # statefull close
my_client_context.term() # graceful termination / release of resources ( no MEM leaks )