pyzmq SUB订阅者如何检测脱机PUB发布者?

时间:2016-03-02 11:11:39

标签: python zeromq publish-subscribe pyzmq

SUB -scriber如何确保另一方有 PUB -lisher,否则无法启动所有?

详细信息:虽然一切都适用于我的 SUB -scriber代码,其中包含正在运行的远程 PUB -lisher,当我.connect() +订阅我的客户端到虚拟服务器说localhost时,它没有注意到没有 PUB - lishers正在运行,它只是启动并等待。

我是用标准程序做的:

    sock = context.socket(zmq.SUB)
    sock.connect("tcp://{}:{}".format(host, port))
    topic_filter = 'blah'
    sock.setsockopt_string(zmq.SUBSCRIBE, topic_filter)
    # here should come something that warns about offline publisher...

1 个答案:

答案 0 :(得分:1)

唯一的PUB / SUB无法创建此

ZeroMQ在概念上和实践上都是一个功能强大的工具箱。一个人不应该试图“弯曲”图书馆原语 - 这些图书馆本身可以被理解,而不仅仅是用于更复杂的消息传递和信令目的的构建块,而不是现实生活中的解决方案---以便做的事情是主要不包括在最初的 S caleable F ormal C 通信 P attern design原型中。

PUB/SUB 原型只是 PUB/SUB

PUB - 播放当前所有SUB的所有广告,如果有的话,每个广告 SUB 听取已经到达的内容(如果有任何内容到达,则应用过滤器...是的,过滤SUB - 侧载网络。)

仍然 - 可以设计一种多原型方法来解决这个问题。

让我为最直接的方案草拟一个基本方案。

假设您完全掌控双方(设计方面和实施方式)。

# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
#
# [Side A]
#        |_____aKnockSOCK = context.socket( zmq.PAIR )
#        |     + .setsockopt( zmq.CONFLATE )
#        |     + .bind()
#        |
#        |_____anEmitSOCK = context.socket( zmq.PUB )
#              + .bind()
#
isNotReceivedSigEXIT  = False
while( isNotReceviedSigEXIT ):
       if ( 0 == aKnockSOCK.poll( aFastPollIN, zmq.POLLIN ) ):
           # nobody new knocking to setup ...
           # ------------------------------------------------
           # do the main job,
           #    with countdown segmentation
           #    to escape to the outer loop
           #    so as to check for new SUB-s
           #    knocking as they come to the show
           # ------------------------------------------------
       else:
           aKnockSOCK.send( "aKnockSOCK ACK: service is ready. Go .connect()" )
#
# --------------------------------------------------------
# ZeroMQ resources graceful termination 
#        socket closes + context dismantle & clean exit



# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
#
#[Side B]
#        |_____aKnockSOCK = context.socket( zmq.PAIR )
#        |     + .setsockopt( zmq.CONFLATE )
#        |
#        |_____aRecvrSOCK = context.socket( zmq.SUB )
#
#
isToBreakEXIT = False
for nthAttempt in range( 10 ):
    if ( isToBreakEXIT ):
         break
    try:
          aKnockSOCK.connect( ... )
    except:
          ReportConnectERROR( ... )
          sleep( ... )
          continue
    # ---------------------------------- once local aKnockSOCK got instantiated
    for kthPoll in range( 10 ):
        if ( 0 == aKnockSOCK.poll( aLongPollIN, zmq.POLLIN ) ):
           sleep( thisCouldBeAddedToLongPollIN )
        else:
           # ----------------------------------------- .recv() + dismantle
           aKnockSOCK.recv()
           aKnockSOCK.setsockopt( zmq.LINGER, 0 )
           aKnockSOCK.close()
           # ----------------------------------------- .connect() + use
           aRecvrSOCK.connect( ... )
           aRecvrSOCK.setsockopt( zmq.SUBSCRIBE, ... )
           # ----------------------------------------- [Side B] main job start
           # ----------------------------------------- [Side B] main job end
           isToBreakEXIT = True
           break
    pass
# --------------------------------------------------------
# ZeroMQ resources graceful termination 
#        socket closes + context dismantle & clean exit