- fixed #63 (Better event loop in WebSocketApp)

This commit is contained in:
liris
2014-03-18 07:59:08 +09:00
parent 562f0e60bf
commit 3940044e81

View File

@@ -45,6 +45,7 @@ import time
import logging import logging
import traceback import traceback
import sys import sys
import select
""" """
websocket python client. websocket python client.
@@ -596,10 +597,13 @@ class WebSocket(object):
opcode, data = self.recv_data() opcode, data = self.recv_data()
return data return data
def recv_data(self): def recv_data(self, control_frame=False):
""" """
Recieve data with operation code. Recieve data with operation code.
control_frame: a boolean flag indicating whether to return control frame
data, defaults to False
return value: tuple of operation code and string(byte array) value. return value: tuple of operation code and string(byte array) value.
""" """
while True: while True:
@@ -622,9 +626,14 @@ class WebSocket(object):
return data return data
elif frame.opcode == ABNF.OPCODE_CLOSE: elif frame.opcode == ABNF.OPCODE_CLOSE:
self.send_close() self.send_close()
return (frame.opcode, None) return (frame.opcode, frame.data)
elif frame.opcode == ABNF.OPCODE_PING: elif frame.opcode == ABNF.OPCODE_PING:
self.pong(frame.data) self.pong(frame.data)
if control_frame:
return (frame.opcode, frame.data)
elif frame.opcode == ABNF.OPCODE_PONG:
if control_frame:
return (frame.opcode, frame.data)
def recv_frame(self): def recv_frame(self):
""" """
@@ -693,6 +702,7 @@ class WebSocket(object):
raise ValueError("code is invalid range") raise ValueError("code is invalid range")
try: try:
self.connected = False
self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE) self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE)
timeout = self.sock.gettimeout() timeout = self.sock.gettimeout()
self.sock.settimeout(3) self.sock.settimeout(3)
@@ -711,7 +721,6 @@ class WebSocket(object):
self._closeInternal() self._closeInternal()
def _closeInternal(self): def _closeInternal(self):
self.connected = False
self.sock.close() self.sock.close()
def _send(self, data): def _send(self, data):
@@ -772,7 +781,8 @@ class WebSocketApp(object):
""" """
def __init__(self, url, header=[], def __init__(self, url, header=[],
on_open=None, on_message=None, on_error=None, on_open=None, on_message=None, on_error=None,
on_close=None, keep_running=True, get_mask_key=None): on_close=None, on_ping=None, on_pong=None,
keep_running=True, get_mask_key=None):
""" """
url: websocket url. url: websocket url.
header: custom header for websocket handshake. header: custom header for websocket handshake.
@@ -799,6 +809,8 @@ class WebSocketApp(object):
self.on_message = on_message self.on_message = on_message
self.on_error = on_error self.on_error = on_error
self.on_close = on_close self.on_close = on_close
self.on_ping = on_ping
self.on_pong = on_pong
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
@@ -856,10 +868,18 @@ class WebSocketApp(object):
thread.setDaemon(True) thread.setDaemon(True)
thread.start() thread.start()
while self.keep_running: while True:
data = self.sock.recv() select.select((self.sock.sock, ), (), ())
if data is None: if not self.keep_running:
break break
op_code, data = self.sock.recv_data(True)
if op_code == ABNF.OPCODE_CLOSE:
break
elif op_code == ABNF.OPCODE_PING:
self._callback(self.on_ping, data)
elif op_code == ABNF.OPCODE_PONG:
self._callback(self.on_pong, data)
else:
self._callback(self.on_message, data) self._callback(self.on_message, data)
except Exception as e: except Exception as e:
self._callback(self.on_error, e) self._callback(self.on_error, e)