implement ping/pong timeout

This commit is contained in:
Martin Konecny
2016-03-21 18:18:42 -04:00
parent 0065c354c5
commit a2e215f363

View File

@@ -101,6 +101,7 @@ class WebSocketApp(object):
self.get_mask_key = get_mask_key self.get_mask_key = get_mask_key
self.sock = None self.sock = None
self.last_ping_tm = 0 self.last_ping_tm = 0
self.last_pong_tm = 0
self.subprotocols = subprotocols self.subprotocols = subprotocols
def send(self, data, opcode=ABNF.OPCODE_TEXT): def send(self, data, opcode=ABNF.OPCODE_TEXT):
@@ -155,6 +156,8 @@ class WebSocketApp(object):
if not ping_timeout or ping_timeout <= 0: if not ping_timeout or ping_timeout <= 0:
ping_timeout = None ping_timeout = None
if ping_timeout and ping_interval and ping_interval <= ping_timeout:
raise WebSocketException("Ensure ping_interval > ping_timeout")
if sockopt is None: if sockopt is None:
sockopt = [] sockopt = []
if sslopt is None: if sslopt is None:
@@ -188,9 +191,6 @@ class WebSocketApp(object):
r, w, e = select.select((self.sock.sock, ), (), (), ping_timeout) r, w, e = select.select((self.sock.sock, ), (), (), ping_timeout)
if not self.keep_running: if not self.keep_running:
break break
if ping_timeout and self.last_ping_tm and time.time() - self.last_ping_tm > ping_timeout:
self.last_ping_tm = 0
raise WebSocketTimeoutException("ping timed out")
if r: if r:
op_code, frame = self.sock.recv_data_frame(True) op_code, frame = self.sock.recv_data_frame(True)
@@ -200,6 +200,7 @@ class WebSocketApp(object):
elif op_code == ABNF.OPCODE_PING: elif op_code == ABNF.OPCODE_PING:
self._callback(self.on_ping, frame.data) self._callback(self.on_ping, frame.data)
elif op_code == ABNF.OPCODE_PONG: elif op_code == ABNF.OPCODE_PONG:
self.last_pong_tm = time.time()
self._callback(self.on_pong, frame.data) self._callback(self.on_pong, frame.data)
elif op_code == ABNF.OPCODE_CONT and self.on_cont_message: elif op_code == ABNF.OPCODE_CONT and self.on_cont_message:
self._callback(self.on_data, data, frame.opcode, frame.fin) self._callback(self.on_data, data, frame.opcode, frame.fin)
@@ -210,6 +211,11 @@ class WebSocketApp(object):
data = data.decode("utf-8") data = data.decode("utf-8")
self._callback(self.on_data, data, frame.opcode, True) self._callback(self.on_data, data, frame.opcode, True)
self._callback(self.on_message, data) self._callback(self.on_message, data)
if ping_timeout and self.last_ping_tm \
and self.last_ping_tm - time.time() > ping_timeout \
and self.last_ping_tm - self.last_pong_tm > ping_timeout:
raise WebSocketTimeoutException("ping/pong timed out")
except (Exception, KeyboardInterrupt, SystemExit) as e: except (Exception, KeyboardInterrupt, SystemExit) as e:
self._callback(self.on_error, e) self._callback(self.on_error, e)
if isinstance(e, SystemExit): if isinstance(e, SystemExit):