像其他人一样,我正在使用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的io_loop是在应用程序启动时创建的全局ioloop:
ioloop.install()
io_loop = IOLoop.instance()它实际上是Tornado IOLoop的ZMQ子类的一个实例。你知道是什么导致了这个错误吗?我有一些清理方法,on_connection_close和on_close,但它们似乎在任何时候都不会被调用。
哦,这是Python2.7.8,ZeroMQ 4.0.4,PyZMQ 14.4.0 (14.3.1也发生了同样的事情)。
提前感谢
发布于 2016-05-27 20:11:35
确保在主线程内调用_set_up_sockets。
由于您只有一个IOLoop,zmq FAQ清楚地指出您需要在同一线程中创建和使用套接字。
https://stackoverflow.com/questions/26517198
复制相似问题