From d3b9eea23a3d84e36230d6eaaa74aac915bdb3a1 2014-09-14 22:22:05 From: Richard Everson Date: 2014-09-14 22:22:05 Subject: [PATCH] Check time of last ping before timing out a missing pong. --- diff --git a/IPython/html/base/zmqhandlers.py b/IPython/html/base/zmqhandlers.py index 1569bca..768e544 100644 --- a/IPython/html/base/zmqhandlers.py +++ b/IPython/html/base/zmqhandlers.py @@ -109,6 +109,7 @@ WS_PING_INTERVAL = 30000 class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler): ping_callback = None + last_ping = 0 last_pong = 0 @property @@ -151,7 +152,8 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler): # start the pinging if self.ping_interval > 0: - self.last_pong = ioloop.IOLoop.instance().time() + self.last_ping = ioloop.IOLoop.instance().time() # Remember time of last ping + self.last_pong = self.last_ping self.ping_callback = ioloop.PeriodicCallback(self.send_ping, self.ping_interval) self.ping_callback.start() @@ -161,15 +163,19 @@ class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler): self.ping_callback.stop() return - # check for timeout on pong - since_last_pong = 1e3 * (ioloop.IOLoop.instance().time() - self.last_pong) - if since_last_pong > self.ping_timeout: + # check for timeout on pong. Make sure that we really have sent a recent ping in + # case the machine with both server and client has been suspended since the last ping. + now = ioloop.IOLoop.instance().time() + since_last_pong = 1e3 * (now - self.last_pong) + since_last_ping = 1e3 * (now - self.last_ping) + if since_last_ping < 2*self.ping_interval and since_last_pong > self.ping_timeout: self.log.warn("WebSocket ping timeout after %i ms.", since_last_pong) self.close() return self.ping(b'') - + self.last_ping = now + def on_pong(self, data): self.last_pong = ioloop.IOLoop.instance().time()