Fixed _XHR_PollingTransport
This commit is contained in:
parent
018e566049
commit
28cfadc593
4 changed files with 44 additions and 45 deletions
|
|
@ -15,7 +15,6 @@ var main = io.of('').on('connection', function(socket) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
socket.on('emit', function() {
|
socket.on('emit', function() {
|
||||||
console.log('hey');
|
|
||||||
socket.emit('emit_response');
|
socket.emit('emit_response');
|
||||||
});
|
});
|
||||||
socket.on('emit_with_payload', function(payload) {
|
socket.on('emit_with_payload', function(payload) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class BaseNamespace(object):
|
||||||
|
|
||||||
def __init__(self, _transport, path):
|
def __init__(self, _transport, path):
|
||||||
self._transport = _transport
|
self._transport = _transport
|
||||||
self._path = path
|
self.path = path
|
||||||
self._callback_by_event = {}
|
self._callback_by_event = {}
|
||||||
self.initialize()
|
self.initialize()
|
||||||
|
|
||||||
|
|
@ -32,11 +32,11 @@ class BaseNamespace(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def message(self, data='', callback=None):
|
def message(self, data='', callback=None):
|
||||||
self._transport.message(self._path, data, callback)
|
self._transport.message(self.path, data, callback)
|
||||||
|
|
||||||
def emit(self, event, *args, **kw):
|
def emit(self, event, *args, **kw):
|
||||||
callback, args = find_callback(args, kw)
|
callback, args = find_callback(args, kw)
|
||||||
self._transport.emit(self._path, event, args, callback)
|
self._transport.emit(self.path, event, args, callback)
|
||||||
|
|
||||||
def on(self, event, callback):
|
def on(self, event, callback):
|
||||||
'Define a callback to handle a custom event emitted by the server'
|
'Define a callback to handle a custom event emitted by the server'
|
||||||
|
|
@ -44,19 +44,19 @@ class BaseNamespace(object):
|
||||||
|
|
||||||
def on_connect(self):
|
def on_connect(self):
|
||||||
'Called after server connects; you can override this method'
|
'Called after server connects; you can override this method'
|
||||||
_log.debug('[connect]')
|
_log.debug('%s [connect]', self.path)
|
||||||
|
|
||||||
def on_disconnect(self):
|
def on_disconnect(self):
|
||||||
'Called after server disconnects; you can override this method'
|
'Called after server disconnects; you can override this method'
|
||||||
_log.debug('[disconnect]')
|
_log.debug('%s [disconnect]', self.path)
|
||||||
|
|
||||||
def on_heartbeat(self):
|
def on_heartbeat(self):
|
||||||
'Called after server sends a heartbeat; you can override this method'
|
'Called after server sends a heartbeat; you can override this method'
|
||||||
_log.debug('[heartbeat]')
|
_log.debug('%s [heartbeat]', self.path)
|
||||||
|
|
||||||
def on_message(self, data):
|
def on_message(self, data):
|
||||||
'Called after server sends a message; you can override this method'
|
'Called after server sends a message; you can override this method'
|
||||||
_log.info('[message] %s', data)
|
_log.info('%s [message] %s', self.path, data)
|
||||||
|
|
||||||
def on_event(self, event, *args):
|
def on_event(self, event, *args):
|
||||||
"""
|
"""
|
||||||
|
|
@ -69,27 +69,27 @@ class BaseNamespace(object):
|
||||||
if callback:
|
if callback:
|
||||||
arguments.append('callback(*args)')
|
arguments.append('callback(*args)')
|
||||||
callback(*args)
|
callback(*args)
|
||||||
_log.info('[event] %s(%s)', event, ', '.join(arguments))
|
_log.info('%s [event] %s(%s)', self.path, event, ', '.join(arguments))
|
||||||
|
|
||||||
def on_error(self, reason, advice):
|
def on_error(self, reason, advice):
|
||||||
'Called after server sends an error; you can override this method'
|
'Called after server sends an error; you can override this method'
|
||||||
_log.info('[error] %s', advice)
|
_log.info('%s [error] %s', self.path, advice)
|
||||||
|
|
||||||
def on_noop(self):
|
def on_noop(self):
|
||||||
'Called after server sends a noop; you can override this method'
|
'Called after server sends a noop; you can override this method'
|
||||||
_log.info('[noop]')
|
_log.info('%s [noop]', self.path)
|
||||||
|
|
||||||
def on_open(self, *args):
|
def on_open(self, *args):
|
||||||
_log.info('[open] %s', args)
|
_log.info('%s [open] %s', self.path, args)
|
||||||
|
|
||||||
def on_close(self, *args):
|
def on_close(self, *args):
|
||||||
_log.info('[close] %s', args)
|
_log.info('%s [close] %s', self.path, args)
|
||||||
|
|
||||||
def on_retry(self, *args):
|
def on_retry(self, *args):
|
||||||
_log.info('[retry] %s', args)
|
_log.info('%s [retry] %s', self.path, args)
|
||||||
|
|
||||||
def on_reconnect(self, *args):
|
def on_reconnect(self, *args):
|
||||||
_log.info('[reconnect] %s', args)
|
_log.info('%s [reconnect] %s', self.path, args)
|
||||||
|
|
||||||
def _find_event_callback(self, event):
|
def _find_event_callback(self, event):
|
||||||
# Check callbacks defined by on()
|
# Check callbacks defined by on()
|
||||||
|
|
@ -142,6 +142,7 @@ class SocketIO(object):
|
||||||
if path:
|
if path:
|
||||||
self._transport.connect(path)
|
self._transport.connect(path)
|
||||||
namespace = Namespace(self._transport, path)
|
namespace = Namespace(self._transport, path)
|
||||||
|
namespace.on_connect()
|
||||||
self._namespace_by_path[path] = namespace
|
self._namespace_by_path[path] = namespace
|
||||||
return namespace
|
return namespace
|
||||||
|
|
||||||
|
|
@ -164,12 +165,13 @@ class SocketIO(object):
|
||||||
if for_callbacks and not self._transport.has_ack_callback:
|
if for_callbacks and not self._transport.has_ack_callback:
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
packet = self._transport.recv_packet().next()
|
for packet in self._transport.recv_packet():
|
||||||
self._process_packet(packet)
|
try:
|
||||||
|
self._process_packet(packet)
|
||||||
|
except _PacketError as e:
|
||||||
|
_log.warn('[packet error] %s', e)
|
||||||
except _TimeoutError:
|
except _TimeoutError:
|
||||||
pass
|
pass
|
||||||
except _PacketError as e:
|
|
||||||
_log.warn('[packet error] %s', e)
|
|
||||||
self.heartbeat_pacemaker.send(elapsed_time)
|
self.heartbeat_pacemaker.send(elapsed_time)
|
||||||
except SocketIOConnectionError as e:
|
except SocketIOConnectionError as e:
|
||||||
try:
|
try:
|
||||||
|
|
@ -366,12 +368,3 @@ def _get_socketIO_session(secure, base_url, **kw):
|
||||||
id=response_parts[0],
|
id=response_parts[0],
|
||||||
heartbeat_timeout=int(response_parts[1]),
|
heartbeat_timeout=int(response_parts[1]),
|
||||||
server_supported_transports=response_parts[3].split(','))
|
server_supported_transports=response_parts[3].split(','))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
requests_log = logging.getLogger('requests')
|
|
||||||
requests_log.setLevel(logging.WARNING)
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
|
||||||
socketIO = SocketIO('localhost', 8000)
|
|
||||||
socketIO.emit('aaa')
|
|
||||||
socketIO.wait()
|
|
||||||
|
|
|
||||||
|
|
@ -140,14 +140,14 @@ class BaseMixin(TestCase):
|
||||||
|
|
||||||
def test_namespaces(self):
|
def test_namespaces(self):
|
||||||
'Behave differently in different namespaces'
|
'Behave differently in different namespaces'
|
||||||
mainNamespace = self.socketIO.define(Namespace)
|
main_namespace = self.socketIO.define(Namespace)
|
||||||
chatNamespace = self.socketIO.define(Namespace, '/chat')
|
chat_namespace = self.socketIO.define(Namespace, '/chat')
|
||||||
newsNamespace = self.socketIO.define(Namespace, '/news')
|
news_namespace = self.socketIO.define(Namespace, '/news')
|
||||||
newsNamespace.emit('emit_with_payload', PAYLOAD)
|
news_namespace.emit('emit_with_payload', PAYLOAD)
|
||||||
self.socketIO.wait(self.wait_time_in_seconds)
|
self.socketIO.wait(self.wait_time_in_seconds)
|
||||||
self.assertEqual(mainNamespace.args_by_event, {})
|
self.assertEqual(main_namespace.args_by_event, {})
|
||||||
self.assertEqual(chatNamespace.args_by_event, {})
|
self.assertEqual(chat_namespace.args_by_event, {})
|
||||||
self.assertEqual(newsNamespace.args_by_event, {
|
self.assertEqual(news_namespace.args_by_event, {
|
||||||
'emit_with_payload_response': (PAYLOAD,),
|
'emit_with_payload_response': (PAYLOAD,),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,9 @@ class _XHR_PollingTransport(_AbstractTransport):
|
||||||
base_url, socketIO_session.id)
|
base_url, socketIO_session.id)
|
||||||
self._connected = True
|
self._connected = True
|
||||||
self._http_session = _prepare_http_session(kw)
|
self._http_session = _prepare_http_session(kw)
|
||||||
|
# Create connection
|
||||||
|
for packet_text in self.recv_packet():
|
||||||
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connected(self):
|
def connected(self):
|
||||||
|
|
@ -156,7 +159,7 @@ class _XHR_PollingTransport(_AbstractTransport):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _params(self):
|
def _params(self):
|
||||||
return dict(t=time.time())
|
return dict(t=int(time.time()))
|
||||||
|
|
||||||
def send(self, packet_text):
|
def send(self, packet_text):
|
||||||
_get_response(
|
_get_response(
|
||||||
|
|
@ -197,7 +200,10 @@ class _JSONP_PollingTransport(_AbstractTransport):
|
||||||
base_url, socketIO_session.id)
|
base_url, socketIO_session.id)
|
||||||
self._connected = True
|
self._connected = True
|
||||||
self._http_session = _prepare_http_session(kw)
|
self._http_session = _prepare_http_session(kw)
|
||||||
self._jsonp_id = 0
|
self._id = 0
|
||||||
|
# Create connection
|
||||||
|
for packet_text in self.recv_packet():
|
||||||
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connected(self):
|
def connected(self):
|
||||||
|
|
@ -205,7 +211,7 @@ class _JSONP_PollingTransport(_AbstractTransport):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _params(self):
|
def _params(self):
|
||||||
return dict(t=time.time(), jsonp=self._jsonp_id)
|
return dict(t=int(time.time()), i=self._id)
|
||||||
|
|
||||||
def send(self, packet_text):
|
def send(self, packet_text):
|
||||||
_get_response(
|
_get_response(
|
||||||
|
|
@ -221,11 +227,11 @@ class _JSONP_PollingTransport(_AbstractTransport):
|
||||||
self._http_session.get,
|
self._http_session.get,
|
||||||
self._url,
|
self._url,
|
||||||
params=self._params,
|
params=self._params,
|
||||||
headers={'content-type': 'application/javascript'},
|
headers={'content-type': 'text/javascript; charset=UTF-8'},
|
||||||
timeout=TIMEOUT_IN_SECONDS)
|
timeout=TIMEOUT_IN_SECONDS)
|
||||||
encoded_text = response.text.encode('utf-8')
|
encoded_text = response.text.encode('utf-8')
|
||||||
if not encoded_text.startswith(BOUNDARY):
|
if not encoded_text.startswith(BOUNDARY):
|
||||||
self._jsonp_id, encoded_data = self.DATA_PATTERN.match(
|
self._id, encoded_data = self.DATA_PATTERN.match(
|
||||||
encoded_text).groups()
|
encoded_text).groups()
|
||||||
yield encoded_data.decode('utf-8')
|
yield encoded_data.decode('utf-8')
|
||||||
for packet_text in _yield_text_from_framed_data(encoded_text):
|
for packet_text in _yield_text_from_framed_data(encoded_text):
|
||||||
|
|
@ -261,11 +267,12 @@ def _negotiate_transport(
|
||||||
def _yield_text_from_framed_data(framed_data):
|
def _yield_text_from_framed_data(framed_data):
|
||||||
parts = [x.decode('utf-8') for x in framed_data.split(BOUNDARY)]
|
parts = [x.decode('utf-8') for x in framed_data.split(BOUNDARY)]
|
||||||
for text_length, text in izip(parts[1::2], parts[2::2]):
|
for text_length, text in izip(parts[1::2], parts[2::2]):
|
||||||
if text_length == str(len(text)):
|
if text_length != str(len(text)):
|
||||||
yield text
|
warning = 'invalid declared length=%s for packet_text=%s' % (
|
||||||
warning = 'invalid declared length=%s for packet_text=%s' % (
|
text_length, text)
|
||||||
text_length, text)
|
_log.warn('[packet error] %s', warning)
|
||||||
_log.warn('[packet error] %s', warning)
|
continue
|
||||||
|
yield text
|
||||||
|
|
||||||
|
|
||||||
def _get_response(request, *args, **kw):
|
def _get_response(request, *args, **kw):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue