diff --git a/examples/aiohttp/app.py b/examples/aiohttp/app.py index da6397f..260636d 100755 --- a/examples/aiohttp/app.py +++ b/examples/aiohttp/app.py @@ -13,7 +13,7 @@ async def background_task(): """Example of how to send server generated events to clients.""" count = 0 while True: - await asyncio.sleep(10) + await sio.sleep(10) count += 1 await sio.emit('my response', {'data': 'Server generated event'}, namespace='/test') @@ -84,5 +84,5 @@ app.router.add_get('/', index) if __name__ == '__main__': - asyncio.ensure_future(background_task()) + sio.start_background_task(background_task) web.run_app(app) diff --git a/socketio/asyncio_server.py b/socketio/asyncio_server.py index c3dc312..857a97a 100644 --- a/socketio/asyncio_server.py +++ b/socketio/asyncio_server.py @@ -106,7 +106,7 @@ class AsyncServer(server.Server): to always leave this parameter with its default value of ``False``. - Note: this method is asynchronous. + Note: this method is a coroutine. """ namespace = namespace or '/' self.logger.info('emitting event "%s" to %s [%s]', event, @@ -148,7 +148,7 @@ class AsyncServer(server.Server): to always leave this parameter with its default value of ``False``. - Note: this method is asynchronous. + Note: this method is a coroutine. """ await self.emit('message', data, room, skip_sid, namespace, callback, **kwargs) @@ -160,7 +160,7 @@ class AsyncServer(server.Server): :param namespace: The Socket.IO namespace to disconnect. If this argument is omitted the default namespace is used. - Note: this method is asynchronous. + Note: this method is a coroutine. """ namespace = namespace or '/' if self.manager.is_connected(sid, namespace=namespace): @@ -185,18 +185,38 @@ class AsyncServer(server.Server): This function returns the HTTP response body to deliver to the client as a byte sequence. - Note: this method is asynchronous. + Note: this method is a coroutine. """ - if not self.manager_initialized: - self.manager_initialized = True - self.manager.initialize() return await self.eio.handle_request(environ) def start_background_task(self, target, *args, **kwargs): - raise RuntimeError('Not implemented, use asyncio.') + """Start a background task using the appropriate async model. + + This is a utility function that applications can use to start a + background task using the method that is compatible with the + selected async mode. + + :param target: the target function to execute. Must be a coroutine. + :param args: arguments to pass to the function. + :param kwargs: keyword arguments to pass to the function. + + The return value is a ``asyncio.Task`` object. + + Note: this method is a coroutine. + """ + return self.eio.start_background_task(target, *args, **kwargs) + + async def sleep(self, seconds=0): + """Sleep for the requested amount of time using the appropriate async + model. - def sleep(self, seconds=0): - raise RuntimeError('Not implemented, use asyncio.') + This is a utility function that applications can use to put a task to + sleep without having to worry about using the correct call for the + selected async mode. + + Note: this method is a coroutine. + """ + return await self.eio.sleep(seconds) async def _emit_internal(self, sid, event, data, namespace=None, id=None): """Send a message to a client.""" @@ -301,6 +321,9 @@ class AsyncServer(server.Server): async def _handle_eio_connect(self, sid, environ): """Handle the Engine.IO connection event.""" + if not self.manager_initialized: + self.manager_initialized = True + self.manager.initialize() self.environ[sid] = environ return await self._handle_connect(sid, '/') diff --git a/socketio/server.py b/socketio/server.py index 7975ec5..cd04a42 100644 --- a/socketio/server.py +++ b/socketio/server.py @@ -345,9 +345,6 @@ class Server(object): This function returns the HTTP response body to deliver to the client as a byte sequence. """ - if not self.manager_initialized: - self.manager_initialized = True - self.manager.initialize() return self.eio.handle_request(environ, start_response) def start_background_task(self, target, *args, **kwargs): @@ -485,6 +482,9 @@ class Server(object): def _handle_eio_connect(self, sid, environ): """Handle the Engine.IO connection event.""" + if not self.manager_initialized: + self.manager_initialized = True + self.manager.initialize() self.environ[sid] = environ return self._handle_connect(sid, '/') diff --git a/tests/test_server.py b/tests/test_server.py index 36ad0f2..62262ee 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -30,7 +30,6 @@ class TestServer(unittest.TestCase): self.assertEqual(s.eio.on.call_count, 3) self.assertEqual(s.binary, True) self.assertEqual(s.async_handlers, True) - self.assertEqual(mgr.initialize.call_count, 1) def test_on_event(self, eio): s = server.Server() @@ -180,6 +179,7 @@ class TestServer(unittest.TestCase): handler.assert_called_once_with('123', 'environ') s.manager.connect.assert_called_once_with('123', '/') s.eio.send.assert_called_once_with('123', '0', binary=False) + self.assertEqual(mgr.initialize.call_count, 1) def test_handle_connect_namespace(self, eio): mgr = mock.MagicMock()