sub和pub套接字丢失消息研究
sub和pub套接字丢失消息研究
问题描述:
使用pub和sub套接字时,无论是先启动服务端还是客户端,在连接之后就会丢失第一个消息。
代码示例:
pub:
import zmq
import time
# 创建上下文
context = zmq.Context()
# 创建 PUB 套接字
socket = context.socket(zmq.PUB)
# 绑定到端口 5555
socket.connect("tcp://192.168.198.198:5555")
for i in range(5):
# 向所有订阅者发布消息
socket.send_string("center-Hello from agent to cneter!")
socket.send_string("app-Hello from agent to app!")
print("Sent message from A")
time.sleep(2) # 每秒发送一次消息
sub:
import zmq
# 创建上下文
context = zmq.Context()
# 创建 SUB 套接字
socket = context.socket(zmq.SUB)
# 连接到主机
socket.bind("tcp://192.168.198.198:5555")
# 订阅所有消息
socket.setsockopt_string(zmq.SUBSCRIBE, "app-")
while True:
# 接收消息
message = socket.recv_string()
msg = message.split("-")[1]
print(f"Received message on agent: {msg}")
结果展示:
发生原因:
订阅者延迟订阅(Subscription delay)
- ZeroMQ 的
SUB套接字会在接收到消息之前向PUB套接字声明自己的订阅主题(例如,订阅的消息类型)。如果SUB套接字在PUB套接字已经开始发布消息之后才连接或开始订阅,那么SUB会错过PUB发布的第一个消息。 - 原因:
PUB套接字在发送第一条消息时,SUB套接字可能还没有来得及完成其订阅过程,导致第一条消息在SUB订阅之前发送,因此会丢失。 - 解决方法:确保
SUB套接字在PUB开始发布之前已经连接并完成订阅。通常,PUB套接字应该启动并保持一段时间,然后再启动SUB套接字,以确保SUB套接字在PUB发布消息时已经准备好接收消息。
解决方案:
在连接之后等待一会,让订阅者连接,然后再发送消息。
pub:
import time
import zmq
def publisher():
context = zmq.Context()
pub_socket = context.socket(zmq.PUB)
pub_socket.bind("tcp://192.168.198.198:5555")
# 等待订阅者连接
print("Publisher waiting for subscribers to connect...")
time.sleep(2) # 等待订阅者连接
# 发布消息
for i in range(5):
message = "Hello, World!"
print(f"Publishing: {message}")
pub_socket.send_string(message)
time.sleep(1)
if __name__ == "__main__":
publisher()
sub:
import zmq
def subscriber():
context = zmq.Context()
sub_socket = context.socket(zmq.SUB)
sub_socket.connect("tcp://192.168.198.198:5555")
# 设置订阅过滤器,订阅所有消息
sub_socket.setsockopt_string(zmq.SUBSCRIBE, "") # 订阅所有消息
# 读取消息
while True:
message = sub_socket.recv_string()
print(f"Received: {message}")
if __name__ == "__main__":
subscriber()
结果展示:

浙公网安备 33010602011771号