Exit the loop if the client wants to disconnect; fixes #30
This commit is contained in:
parent
1506e22458
commit
5ccb32f338
6 changed files with 46 additions and 7 deletions
|
|
@ -1,3 +1,8 @@
|
||||||
|
0.5.3
|
||||||
|
-----
|
||||||
|
- Exit the wait loop if the client wants to disconnect
|
||||||
|
- Set heartbeat_interval to be half of the heartbeat_timeout
|
||||||
|
|
||||||
0.5.2
|
0.5.2
|
||||||
-----
|
-----
|
||||||
- Replaced secure=True with host='https://example.com'
|
- Replaced secure=True with host='https://example.com'
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@ var main = io.of('').on('connection', function(socket) {
|
||||||
fn(payload);
|
fn(payload);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
socket.on('wait_with_disconnect', function() {
|
||||||
|
socket.emit('wait_with_disconnect_response');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var chat = io.of('/chat').on('connection', function (socket) {
|
var chat = io.of('/chat').on('connection', function (socket) {
|
||||||
|
|
|
||||||
2
setup.py
2
setup.py
|
|
@ -9,7 +9,7 @@ CHANGES = open(os.path.join(here, 'CHANGES.rst')).read()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='socketIO-client',
|
name='socketIO-client',
|
||||||
version='0.5.2',
|
version='0.5.3',
|
||||||
description='A socket.io client library',
|
description='A socket.io client library',
|
||||||
long_description=README + '\n\n' + CHANGES,
|
long_description=README + '\n\n' + CHANGES,
|
||||||
license='MIT',
|
license='MIT',
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ class BaseNamespace(object):
|
||||||
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 disconnect(self):
|
||||||
|
self._transport.disconnect(self.path)
|
||||||
|
|
||||||
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'
|
||||||
self._callback_by_event[event] = callback
|
self._callback_by_event[event] = callback
|
||||||
|
|
@ -161,12 +164,14 @@ class SocketIO(object):
|
||||||
self._transport.emit(path, event, args, callback)
|
self._transport.emit(path, event, args, callback)
|
||||||
|
|
||||||
def wait(self, seconds=None, for_callbacks=False):
|
def wait(self, seconds=None, for_callbacks=False):
|
||||||
|
"""Wait in a loop and process events as defined in the namespaces.
|
||||||
|
|
||||||
|
- Omit seconds, i.e. call wait() without arguments, to wait forever.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
warning_screen = _yield_warning_screen(seconds)
|
warning_screen = _yield_warning_screen(seconds)
|
||||||
for elapsed_time in warning_screen:
|
for elapsed_time in warning_screen:
|
||||||
try:
|
try:
|
||||||
if for_callbacks and not self._transport.has_ack_callback:
|
|
||||||
break
|
|
||||||
try:
|
try:
|
||||||
for packet in self._transport.recv_packet():
|
for packet in self._transport.recv_packet():
|
||||||
try:
|
try:
|
||||||
|
|
@ -175,6 +180,8 @@ class SocketIO(object):
|
||||||
_log.warn('[packet error] %s', e)
|
_log.warn('[packet error] %s', e)
|
||||||
except TimeoutError:
|
except TimeoutError:
|
||||||
pass
|
pass
|
||||||
|
if self._stop_waiting(for_callbacks):
|
||||||
|
break
|
||||||
self.heartbeat_pacemaker.send(elapsed_time)
|
self.heartbeat_pacemaker.send(elapsed_time)
|
||||||
except ConnectionError as e:
|
except ConnectionError as e:
|
||||||
try:
|
try:
|
||||||
|
|
@ -186,6 +193,14 @@ class SocketIO(object):
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _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:
|
||||||
|
return True
|
||||||
|
if self.__transport._wants_to_disconnect:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def wait_for_callbacks(self, seconds=None):
|
def wait_for_callbacks(self, seconds=None):
|
||||||
self.wait(seconds, for_callbacks=True)
|
self.wait(seconds, for_callbacks=True)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from . import SocketIO, BaseNamespace, find_callback
|
from . import SocketIO, BaseNamespace, find_callback
|
||||||
|
|
@ -109,15 +110,15 @@ class BaseMixin(object):
|
||||||
|
|
||||||
def test_emit_with_callback_with_payload(self):
|
def test_emit_with_callback_with_payload(self):
|
||||||
'Emit with callback with payload'
|
'Emit with callback with payload'
|
||||||
self.socketIO.emit('emit_with_callback_with_payload',
|
self.socketIO.emit(
|
||||||
self.on_response)
|
'emit_with_callback_with_payload', self.on_response)
|
||||||
self.socketIO.wait_for_callbacks(seconds=self.wait_time_in_seconds)
|
self.socketIO.wait_for_callbacks(seconds=self.wait_time_in_seconds)
|
||||||
self.assertTrue(self.called_on_response)
|
self.assertTrue(self.called_on_response)
|
||||||
|
|
||||||
def test_emit_with_callback_with_multiple_payloads(self):
|
def test_emit_with_callback_with_multiple_payloads(self):
|
||||||
'Emit with callback with multiple payloads'
|
'Emit with callback with multiple payloads'
|
||||||
self.socketIO.emit('emit_with_callback_with_multiple_payloads',
|
self.socketIO.emit(
|
||||||
self.on_response)
|
'emit_with_callback_with_multiple_payloads', self.on_response)
|
||||||
self.socketIO.wait_for_callbacks(seconds=self.wait_time_in_seconds)
|
self.socketIO.wait_for_callbacks(seconds=self.wait_time_in_seconds)
|
||||||
self.assertTrue(self.called_on_response)
|
self.assertTrue(self.called_on_response)
|
||||||
|
|
||||||
|
|
@ -138,6 +139,15 @@ class BaseMixin(object):
|
||||||
'ack_callback_response': (PAYLOAD,),
|
'ack_callback_response': (PAYLOAD,),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def test_wait_with_disconnect(self):
|
||||||
|
'Exit loop when the client wants to disconnect'
|
||||||
|
self.socketIO.define(Namespace)
|
||||||
|
self.socketIO.emit('wait_with_disconnect')
|
||||||
|
timeout_in_seconds = 5
|
||||||
|
start_time = time.time()
|
||||||
|
self.socketIO.wait(timeout_in_seconds)
|
||||||
|
self.assertTrue(time.time() - start_time < timeout_in_seconds)
|
||||||
|
|
||||||
def test_namespace_emit(self):
|
def test_namespace_emit(self):
|
||||||
'Behave differently in different namespaces'
|
'Behave differently in different namespaces'
|
||||||
main_namespace = self.socketIO.define(Namespace)
|
main_namespace = self.socketIO.define(Namespace)
|
||||||
|
|
@ -204,3 +214,6 @@ class Namespace(BaseNamespace):
|
||||||
if callback:
|
if callback:
|
||||||
callback(*args)
|
callback(*args)
|
||||||
self.args_by_event[event] = args
|
self.args_by_event[event] = args
|
||||||
|
|
||||||
|
def on_wait_with_disconnect_response(self):
|
||||||
|
self.disconnect()
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,11 @@ class _AbstractTransport(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._packet_id = 0
|
self._packet_id = 0
|
||||||
self._callback_by_packet_id = {}
|
self._callback_by_packet_id = {}
|
||||||
|
self._wants_to_disconnect = False
|
||||||
|
|
||||||
def disconnect(self, path=''):
|
def disconnect(self, path=''):
|
||||||
|
if not path:
|
||||||
|
self._wants_to_disconnect = True
|
||||||
if not self.connected:
|
if not self.connected:
|
||||||
return
|
return
|
||||||
if path:
|
if path:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue