How to resolve the Tornado + ZMQ error
Like everyone else, I work through PoC chat using Tornado (SockJS-Tornado) + pyzmq.
The general idea is to have instances of N tornadoes, each with associated websocket clients, exchanging messages through a ZMQ device. In other words, the websocket client in instance A is published to the ZMQ Forwarder. Instances B and C have handlers that are subscribed to the Forwarder so that the corresponding topics are passed to websocket clients B and C. And yes, clients in B and C also have publisher sockets that are published to the Forwarder.
Everything works fine, but my problem is that if one of the connected clients disconnects unexpectedly (for example, closes or refreshes the browser tab), I get streams of errors like this:
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
So, there is one Context at the application level, but each handler instantiated gets its own Publisher and Subscriber sockets. Subscriber sockets use ZMQStream, for example:
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)
The ioloop passed to ZMQStream is the global io_loop created when the application starts:
ioloop.install() io_loop = IOLoop.instance()
It is actually an instance of the ZMQ subclass of Tornado IOLoop. Any idea what is causing this error? I have cleanup methods, on_connection_close
and on_close
, but they don't seem to be called at any point.
Oh, this is Python 2.7.8, ZeroMQ 4.0.4, PyZMQ 14.4.0 (same thing happened with 14.3.1).
Thank you in advance
source to share