You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中ZeroMQ Poller无法接收消息的原因排查

问题分析与修复方案

你的Poller脚本没输出,主要是两个关键逻辑错误导致的,我来给你拆解并修正:

1. ROUTER和DEALER的身份不匹配,消息无法送达

ROUTER要给DEALER发消息,必须知道DEALER的身份标识(identity)。但你的ROUTER代码里硬写了identity = b'electrode-service',而DEALER的身份默认是ZeroMQ自动生成的随机值,两者根本对不上,所以消息根本发不到DEALER那边。

另外,ROUTER发送的是多部分消息([身份, 内容]),DEALER这边用recv()只能拿到第一部分(身份),正确的做法是用recv_multipart()来完整接收。

2. SUB套接字的使用搞反了绑定/连接逻辑

SUB套接字的正确用法是**连接(connect)**到PUB套接字的绑定地址,而不是自己绑定地址。你现在让SUB绑定了ipc:///tmp/fast-service,但没有对应的PUB端往这个地址发消息,SUB自然收不到任何内容。


修正后的完整代码

先改ROUTER服务器:先获取DEALER的身份再发消息

ROUTER需要先收到DEALER的一条消息,才能拿到它的身份,之后才能精准发送:

import zmq
import time

def main():
    context = zmq.Context()
    router = context.socket(zmq.ROUTER)
    router.bind("ipc:///tmp/interface-transducer")
    
    print("等DEALER发消息过来拿身份...")
    # 接收DEALER的消息,第一部分就是DEALER的身份
    dealer_identity, msg = router.recv_multipart()
    print(f"拿到DEALER身份: {dealer_identity}")
    
    # 用这个身份循环发消息
    while True:
        router.send_multipart([dealer_identity, b'[1,2]'])
        print("给DEALER发了一条消息")
        time.sleep(1)

if __name__ == "__main__":
    main()

再改Poller监听脚本:修正DEALER接收方式,调整SUB连接逻辑

import zmq

context = zmq.Context()

# DEALER部分:先给ROUTER发一条消息,把自己的身份传过去
receiver = context.socket(zmq.DEALER)
# (可选)如果你想固定DEALER身份,可以手动设置,这样ROUTER不用等消息就能发
# receiver.setsockopt(zmq.IDENTITY, b'electrode-service')
receiver.connect("ipc:///tmp/interface-transducer")
# 发一条初始消息,让ROUTER拿到身份
receiver.send(b'我是DEALER,快给我发消息!')

# SUB部分:改成连接到PUB的绑定地址
subscriber = context.socket(zmq.SUB)
subscriber.connect("ipc:///tmp/fast-service")  # 这里对应PUB要bind的地址
subscriber.setsockopt(zmq.SUBSCRIBE, b"10001")

# 初始化Poller
poller = zmq.Poller()
poller.register(receiver, zmq.POLLIN)
poller.register(subscriber, zmq.POLLIN)

# 循环监听消息
while True:
    try:
        socks = dict(poller.poll())
    except KeyboardInterrupt:
        print("\n用户终止程序")
        break
    
    if receiver in socks:
        # 用recv_multipart完整接收ROUTER的多部分消息
        parts = receiver.recv_multipart()
        print(f"DEALER收到消息: {parts}")
    
    if subscriber in socks:
        msg = subscriber.recv()
        print(f"SUBSCRIBER收到消息: {msg}")

测试SUB的PUB脚本(可选)

如果要测试SUB的功能,运行这个PUB脚本:

import zmq
import time

def main():
    context = zmq.Context()
    pub = context.socket(zmq.PUB)
    pub.bind("ipc:///tmp/fast-service")
    
    while True:
        # 发送带订阅前缀10001的消息
        pub.send(b"10001: 这是来自PUB的测试消息")
        print("给SUB发了一条消息")
        time.sleep(2)

if __name__ == "__main__":
    main()

启动顺序:

  1. 先启动ROUTER服务器
  2. 启动Poller监听脚本
  3. (可选)启动PUB脚本

这样Poller就能正常输出DEALER和SUB收到的消息啦!

内容的提问来源于stack exchange,提问作者hao123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:12:32