- we cannot detect network status at socket.send method, immediately.
  - add ping_timeout argument to WebSocketApp.run_forever method.
    - ping_timeout is timeout seconds after ping.
    - if timeouted, raise WebSocketTimeoutException.
This commit is contained in:
liris
2014-04-04 10:28:40 +09:00
parent c879387010
commit e3ee1c6a72

View File

@@ -42,6 +42,7 @@ import uuid
import hashlib import hashlib
import base64 import base64
import threading import threading
import time
import logging import logging
import traceback import traceback
import sys import sys
@@ -803,7 +804,7 @@ class WebSocket(object):
if "timed out" in e.message: if "timed out" in e.message:
raise WebSocketTimeoutException(e.message) raise WebSocketTimeoutException(e.message)
else: else:
raise e raise
def _recv(self, bufsize): def _recv(self, bufsize):
try: try:
@@ -892,6 +893,7 @@ class WebSocketApp(object):
self.keep_running = keep_running self.keep_running = keep_running
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
def send(self, data, opcode=ABNF.OPCODE_TEXT): def send(self, data, opcode=ABNF.OPCODE_TEXT):
""" """
@@ -911,9 +913,10 @@ class WebSocketApp(object):
def _send_ping(self, interval, event): def _send_ping(self, interval, event):
while not event.wait(interval): while not event.wait(interval):
self.last_ping_tm = time.time()
self.sock.ping() self.sock.ping()
def run_forever(self, sockopt=None, sslopt=None, ping_interval=0): def run_forever(self, sockopt=None, sslopt=None, ping_interval=0, ping_timeout=None):
""" """
run event loop for WebSocket framework. run event loop for WebSocket framework.
This loop is infinite loop and is alive during websocket is available. This loop is infinite loop and is alive during websocket is available.
@@ -922,7 +925,10 @@ class WebSocketApp(object):
sslopt: ssl socket optional dict. sslopt: ssl socket optional dict.
ping_interval: automatically send "ping" command every specified period(second) ping_interval: automatically send "ping" command every specified period(second)
if set to 0, not send automatically. if set to 0, not send automatically.
ping_timeout: timeout(second) if the pong message is not recieved.
""" """
if ping_timeout<=0:
ping_timeout = None
if sockopt is None: if sockopt is None:
sockopt = [] sockopt = []
if sslopt is None: if sslopt is None:
@@ -945,9 +951,14 @@ class WebSocketApp(object):
thread.start() thread.start()
while True: while True:
select.select((self.sock.sock, ), (), ()) 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 time.time() - self.last_ping_tm > ping_timeout:
self.last_ping_tm = 0
raise WebSocketTimeoutException()
if r:
op_code, frame = self.sock.recv_data_frame(True) op_code, frame = self.sock.recv_data_frame(True)
if op_code == ABNF.OPCODE_CLOSE: if op_code == ABNF.OPCODE_CLOSE:
break break