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()