【问题标题】:How to resolve Tornado + ZMQ error如何解决 Tornado + ZMQ 错误
【发布时间】:2014-10-22 21:12:43
【问题描述】:

和其他人一样,我正在使用 Tornado (SockJS-Tornado) + pyzmq 进行聊天 PoC。

总体思路是拥有 N 个 tornado 实例,每个实例都有连接的 websocket 客户端,通过 ZMQ 设备交换消息。换句话说,实例 A 上的 websocket 客户端发布到 ZMQ 转发器。实例 B 和 C 具有订阅转发器的处理程序,以便将匹配的主题中继到 B 和 C 的 websocket 客户端。是的,B 和 C 上的客户端也有发布到转发器的发布者套接字。

这一切正常,但我的问题是,如果其中一个连接的客户端意外断开连接(例如关闭或刷新浏览器选项卡),那么我会收到大量这样的错误:

ERROR:tornado.application:Exception in callback None
Traceback (most recent call last):
  File ".../tornado/ioloop.py", line 836, in start
  fd_obj, handler_func = self._handlers[fd]
KeyError: 246850817
ERROR:tornado.application:Exception in callback None
Traceback (most recent call last):
  File ".../tornado/ioloop.py", line 836, in start
  fd_obj, handler_func = self._handlers[fd]
KeyError: 246850817

因此,在应用程序级别,只有一个上下文,但每个实例化的处理程序都有自己的发布者和订阅者套接字。订阅者套接字使用 ZMQStream,如下所示:

   def _set_up_sockets(self):
    self.publisher = self.context.socket(zmq.PUB)
    self.publisher.connect('tcp://127.0.0.1:5559')
    self.subscriber = self.context.socket(zmq.SUB)
    self.subscriber.connect('tcp://127.0.0.1:5560')
    self.subscriber.setsockopt(zmq.SUBSCRIBE, "_NOROOM_")
    stream = zmqstream.ZMQStream(self.subscriber,
                                 io_loop=self.session.server.io_loop)
    stream.on_recv(self.echo)

传递给ZMQStream的ioloop是应用启动时创建的全局io_loop:

ioloop.install()
io_loop = IOLoop.instance()

它实际上是 Tornado IOLoop 的 ZMQ 子类的一个实例。知道是什么导致了这个错误吗?我有一些清理方法,on_connection_closeon_close,但它们似乎在任何时候都没有被调用。

哦,这是 Python 2.7.8、ZeroMQ 4.0.4、PyZMQ 14.4.0(14.3.1 也发生了同样的事情)。

提前致谢

【问题讨论】:

    标签: python tornado pyzmq


    【解决方案1】:

    确保在主线程中调用 _set_up_sockets。

    由于您只有一个 IOLoop,zmq FAQ 明确指出您需要在同一个线程中创建和使用套接字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-01
      • 2021-12-29
      • 2018-06-30
      • 2012-02-18
      • 2011-08-30
      • 2014-06-13
      • 2011-07-06
      • 2018-09-17
      相关资源
      最近更新 更多