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()
结果展示:


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)