- fixed #63 (Better event loop in WebSocketApp)
This commit is contained in:
34
websocket.py
34
websocket.py
@@ -45,6 +45,7 @@ import time
|
||||
import logging
|
||||
import traceback
|
||||
import sys
|
||||
import select
|
||||
|
||||
"""
|
||||
websocket python client.
|
||||
@@ -596,10 +597,13 @@ class WebSocket(object):
|
||||
opcode, data = self.recv_data()
|
||||
return data
|
||||
|
||||
def recv_data(self):
|
||||
def recv_data(self, control_frame=False):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
while True:
|
||||
@@ -622,9 +626,14 @@ class WebSocket(object):
|
||||
return data
|
||||
elif frame.opcode == ABNF.OPCODE_CLOSE:
|
||||
self.send_close()
|
||||
return (frame.opcode, None)
|
||||
return (frame.opcode, frame.data)
|
||||
elif frame.opcode == ABNF.OPCODE_PING:
|
||||
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):
|
||||
"""
|
||||
@@ -693,6 +702,7 @@ class WebSocket(object):
|
||||
raise ValueError("code is invalid range")
|
||||
|
||||
try:
|
||||
self.connected = False
|
||||
self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE)
|
||||
timeout = self.sock.gettimeout()
|
||||
self.sock.settimeout(3)
|
||||
@@ -711,7 +721,6 @@ class WebSocket(object):
|
||||
self._closeInternal()
|
||||
|
||||
def _closeInternal(self):
|
||||
self.connected = False
|
||||
self.sock.close()
|
||||
|
||||
def _send(self, data):
|
||||
@@ -772,7 +781,8 @@ class WebSocketApp(object):
|
||||
"""
|
||||
def __init__(self, url, header=[],
|
||||
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.
|
||||
header: custom header for websocket handshake.
|
||||
@@ -799,6 +809,8 @@ class WebSocketApp(object):
|
||||
self.on_message = on_message
|
||||
self.on_error = on_error
|
||||
self.on_close = on_close
|
||||
self.on_ping = on_ping
|
||||
self.on_pong = on_pong
|
||||
self.keep_running = keep_running
|
||||
self.get_mask_key = get_mask_key
|
||||
self.sock = None
|
||||
@@ -856,10 +868,18 @@ class WebSocketApp(object):
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
|
||||
while self.keep_running:
|
||||
data = self.sock.recv()
|
||||
if data is None:
|
||||
while True:
|
||||
select.select((self.sock.sock, ), (), ())
|
||||
if not self.keep_running:
|
||||
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)
|
||||
except Exception as e:
|
||||
self._callback(self.on_error, e)
|
||||
|
Reference in New Issue
Block a user