From 52840fcbf8da498f7a846f63d8090ecfa38e9e31 Mon Sep 17 00:00:00 2001 From: MinRK Date: Tue, 15 Jul 2014 22:14:49 -0700 Subject: [PATCH] send ping every 30 seconds to keep websockets alive --- IPython/html/base/zmqhandlers.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/IPython/html/base/zmqhandlers.py b/IPython/html/base/zmqhandlers.py index 3e3f45123..d69155bd4 100644 --- a/IPython/html/base/zmqhandlers.py +++ b/IPython/html/base/zmqhandlers.py @@ -17,6 +17,7 @@ except ImportError: import logging import tornado +from tornado import ioloop from tornado import web from tornado import websocket @@ -103,8 +104,12 @@ class ZMQStreamHandler(websocket.WebSocketHandler): """ return True +# ping interval for keeping websockets alive (30 seconds) +WS_PING_INTERVAL = 30000 class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler): + ping_callback = None + def set_default_headers(self): """Undo the set_default_headers in IPythonHandler @@ -124,6 +129,16 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler): self.session = Session(config=self.config) self.save_on_message = self.on_message self.on_message = self.on_first_message + self.ping_callback = ioloop.PeriodicCallback(self.send_ping, WS_PING_INTERVAL) + self.ping_callback.start() + + def send_ping(self): + """send a ping to keep the websocket alive""" + if self.stream.closed() and self.ping_callback is not None: + self.ping_callback.stop() + return + + self.ping(b'') def _inject_cookie_message(self, msg): """Inject the first message, which is the document cookie,