需求驱动
我司用到 zeroMQ 进行数据传输,为了进行模拟测试,需要Python开发脚本。项目组要求我用python测试该接口(嗯,好像python啥都能干)。
我欣然接受了该任务。
通信模型
经过查阅资料,ZMQ的通信模型有三种:
1、Request-Reply 模型
客户端发送请求,服务端回应请求,客户端接收应答,为一次信息传输。
2、Publisher-Subscriber 模型
服务端广播消息,客户端接收消息,为一次信息传输
3、Parallel Pipeline 模型
服务端将消息发到各个客户端,客户端将消息处理后,再返回给服务端汇总,为一次传输。这个过程看起来像应答模式,为了把方便理解,举个例子:
服务端需要统计各个服务器的资源使用情况,将消息发给各个客户端,客户端收到消息后,将自己的资源使用情况都发给服务端,服务端将这些消息生成报告给运维人员。
经过跟开发沟通,我司采用的是 Publisher-Subscriber 传输模型。所以,我这里也是基于该模型进行脚本开发。我当然可以开发所有模型的脚本,感觉这样的学习更全面些。懂很多固然很好,但人生苦短,按需分配时间吧!
通信脚本
功能描述:数据传输方式,是以字符串进行传输,通过判断Topic(定义为REPORT字段)来筛选数据。
服务端PUB
# -*-coding:utf-8-*-
import zmq
context = zmq.Context() # 创建zmq上下文管理器
socket = context.socket(zmq.PUB) # 创建PUB模式的服务器
socket.bind("tcp://*:5556") # 指定消息发送端口
while True:
Topics = "REPORT"
data = {
"messageId": "a9f1f33d-0d09-493f-a257-05707df2afbb",
"action": "report",
"payload": {
"solution": 2,
"device": {
"id": "90014a48414732650503261b95364500",
"type": "EAIS650-E"
},
"channel": {
"id": 3,
"name": "sz",
"position": "door"
},
"model": {
"id": 225,
"classify": 101,
"version": "version_1593688064476",
"algorithmType": "RFB"
},
"originalImage": {
"fid": "6,01e12065a0a9",
"url": "10.12.1.219:8081",
"publicUrl": "10.12.1.219:8081",
"count": 1
},
"labeledImage": {
"fid": "6,01e12065a0a9",
"url": "10.12.1.219:8081",
"publicUrl": "10.12.1.219:8081",
"count": 1,
"boxs": [{
"label": "napkin",
"pos": [421.978, 216.305, 518.372, 338.363]
},
{
"label": "napkin",
"pos": [421.978, 216.305, 518.372, 338.363]
},
{
"label": "lion",
"pos": [421.978, 216.305, 518.372, 338.363]
},
{
"label": "lion",
"pos": [421.978, 216.305, 518.372, 338.363]
}
]
}
}
}
socket.send_string("{} {}".format(Topics, str(data))) # 发送消息,消息里包含Topic
socket.send_string("no topic of msg") # 发送消息,消息里不包含Topic
客户端SUB
# -*-coding:utf-8-*-
import zmq
context = zmq.Context() # 创建zmq上下文管理器
socket = context.socket(zmq.SUB) # 创建SUB模式的客户端,要求服务端为PUB
print("Collecting updates from weather server...")
socket.connect("tcp://10.12.1.56:5556") # 连接服务器端口
socket.setsockopt_string(zmq.SUBSCRIBE, "REPORT") # 订阅zmq,消息过滤,为空默认全部接收
json_msg = socket.recv_string()
print("json_msg:", json_msg)
自测结果:
如图,在运行服务器之后,再运行客户端,可以收到请求Topic为REPORT的请求,并把其他信息过滤掉了。
项目实战
实际应用中,我需要模拟PUB给客户端提供消息,客户端收到消息后,就会把数据储存起来。所以,我只需要运行上面的服务端脚本即可,测试结果如下: