Prepare to check against master branch
This commit is contained in:
parent
5ecc5fb36c
commit
ebd18b7017
3 changed files with 75 additions and 38 deletions
|
|
@ -1,11 +1,11 @@
|
|||
import json
|
||||
|
||||
from .exceptions import ConnectionError, TimeoutError, PacketError
|
||||
from .heartbeats import HeartbeatThread
|
||||
from .logs import LoggingMixin
|
||||
from .namespaces import EngineIONamespace, SocketIONamespace, find_callback
|
||||
from .parsers import parse_host, parse_socketIO_data
|
||||
from .symmetries import encode_string, get_character
|
||||
from .parsers import (
|
||||
parse_host, parse_engineIO_session,
|
||||
parse_socketIO_data, format_socketIO_data)
|
||||
from .symmetries import get_character
|
||||
from .transports import XHR_PollingTransport, prepare_http_session, TRANSPORTS
|
||||
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ class EngineIO(LoggingMixin):
|
|||
return self.__transport
|
||||
except AttributeError:
|
||||
pass
|
||||
self._get_engineIO_session()
|
||||
self._engineIO_session = self._get_engineIO_session()
|
||||
self._negotiate_transport()
|
||||
self._reset_heartbeat()
|
||||
self._connect_namespaces()
|
||||
|
|
@ -60,18 +60,13 @@ class EngineIO(LoggingMixin):
|
|||
try:
|
||||
engineIO_packet_type, engineIO_packet_data = next(
|
||||
transport.recv_packet())
|
||||
|
||||
except (TimeoutError, ConnectionError) as e:
|
||||
if not self._wait_for_connection:
|
||||
raise
|
||||
warning = Exception('[waiting for connection] %s' % e)
|
||||
warning_screen.throw(warning)
|
||||
assert engineIO_packet_type == 0
|
||||
value_by_name = json.loads(encode_string(engineIO_packet_data))
|
||||
self._session_id = value_by_name['sid']
|
||||
self._ping_interval = value_by_name['pingInterval'] / float(1000)
|
||||
self._ping_timeout = value_by_name['pingTimeout'] / float(1000)
|
||||
self._transport_upgrades = value_by_name['upgrades']
|
||||
return parse_engineIO_session(engineIO_packet_data)
|
||||
|
||||
def _negotiate_transport(self):
|
||||
self.__transport = self._get_transport('xhr-polling')
|
||||
|
|
@ -83,7 +78,7 @@ class EngineIO(LoggingMixin):
|
|||
pass
|
||||
self._heartbeat_thread = HeartbeatThread(
|
||||
send_heartbeat=self.__transport._ping,
|
||||
relax_interval_in_seconds=self._ping_interval,
|
||||
relax_interval_in_seconds=self._engineIO_session.ping_interval,
|
||||
hurry_interval_in_seconds=1)
|
||||
self._heartbeat_thread.start()
|
||||
|
||||
|
|
@ -129,6 +124,9 @@ class EngineIO(LoggingMixin):
|
|||
|
||||
# Act
|
||||
|
||||
def send(self, engineIO_packet_data):
|
||||
self._message(engineIO_packet_data)
|
||||
|
||||
def _open(self):
|
||||
engineIO_packet_type = 0
|
||||
self._transport.send_packet(engineIO_packet_type, '')
|
||||
|
|
@ -188,7 +186,6 @@ class EngineIO(LoggingMixin):
|
|||
self._heartbeat_thread.relax()
|
||||
|
||||
def _should_stop_waiting(self):
|
||||
# Use __transport to make sure that we do not reconnect inadvertently
|
||||
return self._wants_to_close
|
||||
|
||||
def _process_packets(self):
|
||||
|
|
@ -278,7 +275,7 @@ class SocketIO(EngineIO):
|
|||
for path, namespace in self._namespace_by_path.items():
|
||||
namespace._transport = self.__transport
|
||||
if path:
|
||||
self.__transport.connect(path)
|
||||
self.connect(path)
|
||||
|
||||
def __exit__(self, *exception_pack):
|
||||
self.disconnect()
|
||||
|
|
@ -311,34 +308,29 @@ class SocketIO(EngineIO):
|
|||
|
||||
# Act
|
||||
|
||||
def connect():
|
||||
pass
|
||||
def connect(self, path):
|
||||
socketIO_packet_type = 0
|
||||
socketIO_packet_data = format_socketIO_data(path)
|
||||
self._message(str(socketIO_packet_type) + socketIO_packet_data)
|
||||
|
||||
def disconnect():
|
||||
pass
|
||||
def disconnect(self, path=''):
|
||||
socketIO_packet_type = 1
|
||||
socketIO_packet_data = format_socketIO_data(path)
|
||||
self._message(str(socketIO_packet_type) + socketIO_packet_data)
|
||||
try:
|
||||
namespace = self._namespace_by_path.pop(path)
|
||||
namespace.on_disconnect()
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def emit(self, event, *args, **kw):
|
||||
path = kw.get('path', '')
|
||||
callback, args = find_callback(args, kw)
|
||||
self._emit(path, event, args, callback)
|
||||
|
||||
def _emit(self, path, event, args, callback):
|
||||
ack_id = self._set_ack_callback(callback) if callback else None
|
||||
socketIO_packet_type = 2
|
||||
|
||||
socketIO_packet_data = json.dumps([event] + list(args))
|
||||
if callback:
|
||||
ack_id = self._set_ack_callback(callback) if callback else ''
|
||||
socketIO_packet_data = str(ack_id) + socketIO_packet_data
|
||||
if path:
|
||||
socketIO_packet_data = path + ',' + socketIO_packet_data
|
||||
|
||||
socketIO_packet_data = format_socketIO_data(path, ack_id, args)
|
||||
self._message(str(socketIO_packet_type) + socketIO_packet_data)
|
||||
|
||||
def _set_ack_callback(self, callback):
|
||||
self._ack_id += 1
|
||||
self._callback_by_ack_id[self._ack_id] = callback
|
||||
return self._ack_id
|
||||
|
||||
def send(self, data='', callback=None):
|
||||
args = [data]
|
||||
if callback:
|
||||
|
|
@ -354,8 +346,7 @@ class SocketIO(EngineIO):
|
|||
self.wait(seconds, for_callbacks=True)
|
||||
|
||||
def _should_stop_waiting(self, for_callbacks):
|
||||
# Use __transport to make sure that we do not reconnect inadvertently
|
||||
if for_callbacks and not self.__transport.has_ack_callback:
|
||||
if for_callbacks and not self._has_ack_callback:
|
||||
return True
|
||||
return super(SocketIO, self)._should_stop_waiting()
|
||||
|
||||
|
|
@ -423,5 +414,14 @@ class SocketIO(EngineIO):
|
|||
'Return function that acknowledges the server'
|
||||
return lambda *args: self._ack(path, ack_id, *args)
|
||||
|
||||
def _set_ack_callback(self, callback):
|
||||
self._ack_id += 1
|
||||
self._callback_by_ack_id[self._ack_id] = callback
|
||||
return self._ack_id
|
||||
|
||||
def _get_ack_callback(self, ack_id):
|
||||
return self._callback_by_ack_id.pop(ack_id)
|
||||
|
||||
@property
|
||||
def _has_ack_callback(self):
|
||||
return True if self._callback_by_ack_id else False
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ class EngineIONamespace(LoggingMixin):
|
|||
'Define a callback to handle an event emitted by the server'
|
||||
self._callback_by_event[event] = callback
|
||||
|
||||
def send(self, data):
|
||||
'Send a message'
|
||||
self._io.send(data)
|
||||
|
||||
def on_open(self):
|
||||
"""Called after engine.io connects.
|
||||
You can override this method."""
|
||||
|
|
@ -63,6 +67,18 @@ class SocketIONamespace(EngineIONamespace):
|
|||
self.path = path
|
||||
super(SocketIONamespace, self).__init__(io)
|
||||
|
||||
def connect(self):
|
||||
self._io.connect(self.path)
|
||||
|
||||
def disconnect(self):
|
||||
self._io.disconnect(self.path)
|
||||
|
||||
def emit(self, event, *args, **kw):
|
||||
self._io.emit(event, *args, **kw)
|
||||
|
||||
def send(self, data='', callback=None):
|
||||
self._io.send(data, callback)
|
||||
|
||||
def on_connect(self):
|
||||
"""Called after socket.io connects.
|
||||
You can override this method."""
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import json
|
||||
from collections import namedtuple
|
||||
|
||||
from .symmetries import encode_string, get_byte, get_character, parse_url
|
||||
from .symmetries import (
|
||||
decode_string, encode_string, get_byte, get_character, parse_url)
|
||||
|
||||
|
||||
EngineIOSession = namedtuple('EngineIOSession', [
|
||||
'id', 'ping_interval', 'ping_timeout', 'transport_upgrades'])
|
||||
SocketIOData = namedtuple('SocketIOData', ['path', 'ack_id', 'args'])
|
||||
|
||||
|
||||
|
|
@ -17,6 +20,15 @@ def parse_host(host, port, resource):
|
|||
return is_secure, url
|
||||
|
||||
|
||||
def parse_engineIO_session(engineIO_packet_data):
|
||||
d = json.loads(decode_string(engineIO_packet_data))
|
||||
return EngineIOSession(
|
||||
id=d['sid'],
|
||||
ping_interval=d['pingInterval'] / float(1000),
|
||||
ping_timeout=d['pingTimeout'] / float(1000),
|
||||
transport_upgrades=d['upgrades'])
|
||||
|
||||
|
||||
def encode_engineIO_content(engineIO_packets):
|
||||
parts = []
|
||||
for packet_type, packet_data in engineIO_packets:
|
||||
|
|
@ -42,7 +54,7 @@ def decode_engineIO_content(content):
|
|||
|
||||
|
||||
def parse_socketIO_data(data):
|
||||
data = encode_string(data)
|
||||
data = decode_string(data)
|
||||
if data.startswith('/'):
|
||||
try:
|
||||
path, data = data.split(',', 1)
|
||||
|
|
@ -64,6 +76,15 @@ def parse_socketIO_data(data):
|
|||
return SocketIOData(path=path, ack_id=ack_id, args=args)
|
||||
|
||||
|
||||
def format_socketIO_data(path=None, ack_id=None, args=None):
|
||||
socketIO_packet_data = json.dumps(args) if args else ''
|
||||
if ack_id is not None:
|
||||
socketIO_packet_data = str(ack_id) + socketIO_packet_data
|
||||
if path:
|
||||
socketIO_packet_data = path + ',' + socketIO_packet_data
|
||||
return socketIO_packet_data
|
||||
|
||||
|
||||
def _make_packet_header(packet_string):
|
||||
length_string = str(len(packet_string))
|
||||
header_digits = [0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue