diff --git a/docs/client.rst b/docs/client.rst index 5bf85ad1..a44a5730 100644 --- a/docs/client.rst +++ b/docs/client.rst @@ -65,6 +65,9 @@ or can also be coroutines:: async def message(data): print('I received a message!') +If the server includes arguments with an event, those are passed to the +handler function as arguments. + Catch-All Event Handlers ------------------------ @@ -72,13 +75,13 @@ A "catch-all" event handler is invoked for any events that do not have an event handler. You can define a catch-all handler using ``'*'`` as event name:: @sio.on('*') - def catch_all(event, sid, data): + def catch_all(event, data): pass Asyncio clients can also use a coroutine:: @sio.on('*') - async def catch_all(event, sid, data): + async def catch_all(event, data): pass A catch-all event handler receives the event name as a first argument. The @@ -115,8 +118,8 @@ going to attempt to reconnect immediately after invoking the disconnect handler. As soon as the connection is re-established the connect handler will be invoked once again. -If the server includes arguments with an event, those are passed to the -handler function as arguments. +The ``connect``, ``connect_error`` and ``disconnect`` events have to be +defined explicitly and are not invoked on a catch-all event handler. Connecting to a Server ---------------------- diff --git a/docs/server.rst b/docs/server.rst index e5536961..f02fa3cc 100644 --- a/docs/server.rst +++ b/docs/server.rst @@ -197,6 +197,9 @@ Asyncio servers can also use a coroutine:: A catch-all event handler receives the event name as a first argument. The remaining arguments are the same as for a regular event handler. +The ``connect`` and ``disconnect`` events have to be defined explicitly and are +not invoked on a catch-all event handler. + Connect and Disconnect Event Handlers ------------------------------------- diff --git a/src/socketio/asyncio_client.py b/src/socketio/asyncio_client.py index e98f3373..03b770de 100644 --- a/src/socketio/asyncio_client.py +++ b/src/socketio/asyncio_client.py @@ -431,7 +431,8 @@ async def _trigger_event(self, event, namespace, *args): handler = None if event in self.handlers[namespace]: handler = self.handlers[namespace][event] - elif '*' in self.handlers[namespace]: + elif event not in self.reserved_events and \ + '*' in self.handlers[namespace]: handler = self.handlers[namespace]['*'] args = (event, *args) if handler: diff --git a/src/socketio/asyncio_server.py b/src/socketio/asyncio_server.py index a43430c3..59fab4a2 100644 --- a/src/socketio/asyncio_server.py +++ b/src/socketio/asyncio_server.py @@ -532,7 +532,8 @@ async def _trigger_event(self, event, namespace, *args): handler = None if event in self.handlers[namespace]: handler = self.handlers[namespace][event] - elif '*' in self.handlers[namespace]: + elif event not in self.reserved_events and \ + '*' in self.handlers[namespace]: handler = self.handlers[namespace]['*'] args = (event, *args) if handler: diff --git a/src/socketio/client.py b/src/socketio/client.py index 2078e5de..5046ea86 100644 --- a/src/socketio/client.py +++ b/src/socketio/client.py @@ -92,6 +92,8 @@ class Client(object): fatal errors are logged even when ``engineio_logger`` is ``False``. """ + reserved_events = ['connect', 'connect_error', 'disconnect'] + def __init__(self, reconnection=True, reconnection_attempts=0, reconnection_delay=1, reconnection_delay_max=5, randomization_factor=0.5, logger=False, serializer='default', @@ -625,7 +627,8 @@ def _trigger_event(self, event, namespace, *args): if namespace in self.handlers: if event in self.handlers[namespace]: return self.handlers[namespace][event](*args) - elif '*' in self.handlers[namespace]: + elif event not in self.reserved_events and \ + '*' in self.handlers[namespace]: return self.handlers[namespace]['*'](event, *args) # or else, forward the event to a namespace handler if one exists diff --git a/src/socketio/server.py b/src/socketio/server.py index b8ee435c..cdf255b3 100644 --- a/src/socketio/server.py +++ b/src/socketio/server.py @@ -106,6 +106,8 @@ class Server(object): fatal errors are logged even when ``engineio_logger`` is ``False``. """ + reserved_events = ['connect', 'disconnect'] + def __init__(self, client_manager=None, logger=False, serializer='default', json=None, async_handlers=True, always_connect=False, **kwargs): @@ -741,7 +743,8 @@ def _trigger_event(self, event, namespace, *args): if namespace in self.handlers: if event in self.handlers[namespace]: return self.handlers[namespace][event](*args) - elif '*' in self.handlers[namespace]: + elif event not in self.reserved_events and \ + '*' in self.handlers[namespace]: return self.handlers[namespace]['*'](event, *args) # or else, forward the event to a namespace handler if one exists diff --git a/tests/asyncio/test_asyncio_client.py b/tests/asyncio/test_asyncio_client.py index 06a119d2..b8d5c4ca 100644 --- a/tests/asyncio/test_asyncio_client.py +++ b/tests/asyncio/test_asyncio_client.py @@ -838,6 +838,7 @@ def test_trigger_event(self): c.on('*', catchall_handler) _run(c._trigger_event('foo', '/', 1, '2')) _run(c._trigger_event('bar', '/', 1, '2', 3)) + _run(c._trigger_event('connect', '/')) # should not trigger handler.assert_called_once_with(1, '2') catchall_handler.assert_called_once_with('bar', 1, '2', 3) diff --git a/tests/common/test_client.py b/tests/common/test_client.py index 2c3a93da..a9415efc 100644 --- a/tests/common/test_client.py +++ b/tests/common/test_client.py @@ -943,6 +943,7 @@ def test_trigger_event(self): c.on('*', catchall_handler) c._trigger_event('foo', '/', 1, '2') c._trigger_event('bar', '/', 1, '2', 3) + c._trigger_event('connect', '/') # should not trigger handler.assert_called_once_with(1, '2') catchall_handler.assert_called_once_with('bar', 1, '2', 3)