ZMQ — 基本使用与工具类
一、简介
- 官网:https://zeromq.org/
- ZeroMQ(简称ZMQ)是一个基于消息队列的多线程网络库,其对套接字类型、连接处理、帧、甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字。
- ZMQ是网络通信中新的一层,介于应用层和传输层之间(按照TCP/IP划分),其是一个可伸缩层,可并行运行,分散在分布式系统间。
- ZMQ不是单独的服务,而是一个嵌入式库,它封装了网络通信、消息队列、线程调度等功能,向上层提供简洁的API,应用程序通过加载库文件,调用API函数来实现高性能网络通信。
二、使用
(一) python — zmq
1. 请求响应模式
-
示例:
-
server:
# # Hello World server in Python # Binds REP socket to tcp://*:5555 # Expects b"Hello" from client, replies with b"World" # import time import zmq context = zmq.Context() socket = context.socket(zmq.REP) socket.bind("tcp://*:5555") while True: # Wait for next request from client message = socket.recv() print("Received request: %s" % message) # Do some 'work' time.sleep(1) # Send reply back to client socket.send(b"World")
-
client:
# # Hello World client in Python # Connects REQ socket to tcp://localhost:5555 # Sends "Hello" to server, expects "World" back # import zmq context = zmq.Context() # Socket to talk to server print("Connecting to hello world server…") socket = context.socket(zmq.REQ) socket.connect("tcp://localhost:5555") # Do 10 requests, waiting each time for a response for request in range(10): print("Sending request %s …" % request) socket.send(b"Hello") # Get the reply. message = socket.recv() print("Received reply %s [ %s ]" % (request, message))
-
-
封装工具类:
我们可以看到:对于 TCP 中,绑定ip、端口等代码都基本一致,唯一不同的是处理接收端消息部分的代码,所以我对接收消息部分的代码进行解耦合,封装之后的工具类如下,核心点在于
callback
参数使用,大家有好的建议也可以一起分享一下:-
server:
class ZmqServer: """ zmp 服务端 """ def __init__(self, host, port, callback): """ 初始化 socket 服务端 :param host: socket绑定的ip :param port: socket绑定的端口 :param callback: 处理客户端的回调方法,传递函数名 """ self.host = host self.port = port self.callback = callback # 1. 初始化服务端socket self.context = zmq.Context() self.socket = self.context.socket(zmq.REP) # 'tcp://127.0.0.1:5555' self.url = 'tcp://' + self.host + ":" + str(self.port) self.socket.bind(self.url) def start_server(self): try: # 启动 TCP 服务 print(self.url, '——服务已启动!') # 处理接收端业务代码 self.callback(self.socket) except Exception as e: print('异常:', e) sys.exit() def action(socket): while True: print("wait for client ...") message = socket.recv() print("message from client:", message.decode('utf-8')) socket.send(message) if __name__ == '__main__': zmq_server = ZmqServer('127.0.0.1', 5555, action) zmq_server.start_server()
-
client:
client端的代码同上,暂时还未进行封装
-
2. 发布订阅模式
-
示例
-
server:
import zmq import time import sys context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("tcp://*:5555") while True: msg = input("请输入要发布的信息:").strip() if msg == 'b': sys.exit() socket.send(msg.encode('utf-8')) time.sleep(1)
-
client:
import zmq context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect("tcp://localhost:5555") socket.setsockopt(zmq.SUBSCRIBE,''.encode('utf-8')) # 接收所有消息 while True: response = socket.recv().decode('utf-8'); print("response: %s" % response)
-
参考文献
- 官网:https://zeromq.org/
- 工作模式:https://www.cnblogs.com/yunwangjun-python-520/p/10777375.html