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()

结果展示:

posted @   零の守墓人  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示