Python PyZMQ单向通信

Python PyZMQ单向通信,python,sockets,zeromq,pyzmq,Python,Sockets,Zeromq,Pyzmq,我查看了各种ZMQ消息传递模式,不确定哪种模式适合我的项目。我所要做的就是能够连接到服务器并发送一个命令,而客户端永远不会收到任何东西。在服务器端,我希望能够检查是否有消息,如果有,处理它,否则继续执行其他操作而不阻塞。这样,即使没有连接客户端,服务器也可以继续工作 #client.py while(True): select = raw_input() if select == "1": socket.send(msg1) elif select == "

我查看了各种ZMQ消息传递模式,不确定哪种模式适合我的项目。我所要做的就是能够连接到服务器并发送一个命令,而客户端永远不会收到任何东西。在服务器端,我希望能够检查是否有消息,如果有,处理它,否则继续执行其他操作而不阻塞。这样,即使没有连接客户端,服务器也可以继续工作

#client.py
while(True):
    select = raw_input()
    if select == "1":
       socket.send(msg1)
    elif select == "2":
       socket.send(msg2)
    ...

#server.py
while(True):
    msg = socket.recv() #should not block
    if msg == ...
        #do stuff
    #do other stuff

那么,我应该使用ZMQ的哪种模式来实现这一点呢?示例代码将不胜感激。

首先,由于您希望只使用一个接收消息的套接字进行单向通信,这通常意味着推拉。以下是客户端的一个版本:

import zmq

ctx = zmq.Context.instance()
s = ctx.socket(zmq.PUSH)
url = 'tcp://127.0.0.1:5555'
s.connect(url)

while True:
    msg = raw_input("msg > ")
    s.send(msg)
    if msg == 'quit':
        break
因此,推送套接字发送我们从原始输入获得的消息。应该清楚如何更改该逻辑以生成所需的消息。还有一点好处是,如果键入“退出”,客户端和服务器都将退出

根据应用程序的复杂性,有多种方法来实现非阻塞服务器。我将展示几个示例,从最基本的示例到最强大/可扩展的示例

所有这些服务器示例都假设在顶部设置服务器的拉插座:

import time
import zmq

ctx = zmq.Context.instance()
s = ctx.socket(zmq.PULL)
url = 'tcp://127.0.0.1:5555'
s.bind(url)
第一个示例是简单的非阻塞recv,它会引发zmq。如果没有准备好接收的消息,则再次出现异常:

# server0.py

while True:
    try:
        msg = s.recv(zmq.NOBLOCK) # note NOBLOCK here
    except zmq.Again:
        # no message to recv, do other things
        time.sleep(1)
    else:
        print("received %r" % msg)
        if msg == 'quit':
            break
但这种模式很难扩展到非常简单的情况之外。第二个示例使用轮询器检查套接字上的事件:

# server1.py

poller = zmq.Poller()
poller.register(s)

while True:
    events = dict(poller.poll(0))
    if s in events:
        msg = s.recv()
        print("received %r" % msg)
        if msg == 'quit':
            break
    else:
        # no message to recv, do other things
        time.sleep(1)
在这个玩具示例中,这与第一个非常相似。但是,与第一个不同的是,通过进一步调用poller.register或向poller.poll传递非零超时,可以很容易地扩展到许多套接字或事件

最后一个示例使用eventloop,并在消息到达时实际注册回调。您可以使用这种模式构建非常复杂的应用程序,而且这是一种相当简单的方法,可以编写只在有工作要做时才工作的代码

# server2.py

from zmq.eventloop import ioloop
from zmq.eventloop.zmqstream import ZMQStream

def print_msg(msg):
    print("received %r" % ' '.join(msg))
    if msg[0] == 'quit':
        ioloop.IOLoop.instance().stop()

# register the print_msg callback to be fired
# whenever there is a message on our socket
stream = ZMQStream(s)
stream.on_recv(print_msg)

# do other things in the meantime
tic = time.time()
def do_other_things():
    print("%.3f" % (time.time() - tic))

pc = ioloop.PeriodicCallback(do_other_things, 1000)
pc.start()

# start the eventloop
ioloop.IOLoop.instance().start()
这是处理zmq消息而不阻塞的一些基本方法。你可以抓住这些例子