From be80e623404d18430cf9e31d1b71de4201d45f60 Mon Sep 17 00:00:00 2001 From: Richard Everson Date: Sun, 14 Sep 2014 23:22:05 +0100 Subject: [PATCH] Check time of last ping before timing out a missing pong. --- IPython/html/base/zmqhandlers.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/IPython/html/base/zmqhandlers.py b/IPython/html/base/zmqhandlers.py index 1569bcaa0..768e54490 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()