【问题标题】:zmq.error.ZMQError: Socket operation on non-socket: How to find alive sockets before closing?zmq.error.ZMQError:非套接字上的套接字操作:如何在关闭之前找到活动的套接字?
【发布时间】:2017-07-27 21:36:26
【问题描述】:

在我的应用程序中,我正在创建 2 个套接字并尝试/除此之外:

try:
    socketA.connect("tcp://localhost:5557")
    socketB.bind("tcp://localhost:5558")
except zmq.ZMQError as e:

    if e.errno == zmq.EINVAL:
        logger.error("Endpoint supplied is invalid")
    else:
        logger.error("The ZeroMQ error with an error number {0}".format(e.errno))
        raise ZMQError(e)
    cleanUp()

如果由于某种原因,其中一个套接字不能.connect()/.bind(),我想关闭两个套接字并在cleanUp() 函数中终止上下文,但是在关闭它们之前我怎么知道哪些套接字是活动的?

ZeroMQ 是否在关闭活动套接字之前提供任何有关活动套接字的信息?

【问题讨论】:

    标签: python zeromq pyzmq


    【解决方案1】:

    鉴于上述逻辑,让我们使用另一种方法:

    案例 A: 两个套接字分别执行 .connect() + .bind()
    案例 B: 任何套接字都失败了。

     try:
           socketA.connect(   "tcp://localhost:5557" )
           socketA.setsockopt( zmq.LINGER, 0 )
           try:
                socketB.bind(      "tcp://localhost:5558" )
                socketB.setsockopt( zmq.LINGER, 0 )
    
           except zmq.ZMQError as e:
    
                if ( e.errno in ( zmq.EINVAL, 
                                  zmq.EPROTONOSUPPORT,
                                  zmq.ENOCOMPATPROTO,
                                  zmq.EADDRINUSE,
                                  zmq.EADDRNOTAVAIL,
                                  )
                     ):
                     logger.error( "ZeroMQ TransportClass / Endpoint cannot be setup for [socketB]." )
    
                if ( e.errno in ( zmq.ENODEV,
                                  zmq.ENOTSOCK,
                                  )
                     ):
                     logger.error( "ZeroMQ request was made against a non-existent device or not using a valid socket [socketB]." )
    
                if ( e.errno in ( zmq.ETERM,
                                  zmq.EMTHREAD,
                                  )
                     ):
                     logger.error( "ZeroMQ Context is not in a state to handle this request for [socketB]." )
    
    
                cleanUp( aContextINSTANCE, [ socketA, socketB, ] )
    
      except zmq.ZMQError as e:
    
                if ( e.errno in ( zmq.EINVAL,
                                  zmq.EPROTONOSUPPORT,
                                  zmq.ENOCOMPATPROTO,
                                  )
                     ):
                     logger.error( "ZeroMQ TransportClass / Endpoint cannot be setup for [socketA]." )
    
                if ( e.errno in ( zmq.ETERM,
                                  zmq.EMTHREAD,
                                  )
                     ):
                     logger.error( "ZeroMQ Context is not ready to handle this request for [socketA]." )
    
                if ( e.errno in ( zmq.ENOTSOCK, ) ):
                     logger.error( "ZeroMQ operation was requested, but not on a valid [socketA]." )
    
           cleanUp( aContextINSTANCE, [ socketA, ] )
    
    finally:
          # ...
          pass
    
    def cleanUp( aContextToTERMINATE, aListOfSocketsToCLOSE = [] ):
        for      aSocket in aListOfSocketsToCLOSE:
            try:
                 aSocket.close()             # external responsibility to setup LINGER as zero right at aSocket instantiation point
            except:
                 pass
        try:
             aContextToTERMINATE.term()
        except:
             pass
        finally:
             # ...
             pass
    

    【讨论】:

    • 感谢您的回答!您将 linger 设置为 0 是否有特定原因。我在关闭套接字之前将其设置为 -1,因为我希望数据在线路中可用,即使在发送少量消息后关闭套接字也是如此。
    • 当然有原因。任何非零的LINGER 都会阻止.close() 的尝试,并且分布式系统应该公平到不阻止。即使程序消失,它也应该表现得无阻塞,以免失控——在阻塞状态下,你的代码对发生的事情的控制为零,只是被动地挂在外部事件的沉默中(这不需要永远来 ... )。阻塞资源并失去控制通常不是一个好主意,是吗?
    【解决方案2】:

    我不完全确定“哪些套接字处于活动状态”是什么意思。无论哪个connect/bind 调用失败,两个 套接字都必须关闭。在 C libzmq 术语中,zmq_close 不是zmq_connect/zmq_bind 的对应物,而是zmq_socket。 pyzmq 中的zmq_socket 已被Socket.__init__ 调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-21
      • 2014-09-10
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多