From 8d9ee8b77820a2af11d7c1716f793a610afe306f Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sun, 24 Jul 2016 17:04:42 +0200 Subject: [PATCH] Add FAQ section for demonstrating sending data from different tasks through the same websocket --- docs/faq.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/web.rst | 10 ++++++++++ 2 files changed, 58 insertions(+) diff --git a/docs/faq.rst b/docs/faq.rst index 5af98d2cf17..7bc110abee9 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -81,3 +81,51 @@ Just put data inside *request*:: See https://github.com/aio-libs/aiohttp_session code for inspiration, ``aiohttp_session.get_session(request)`` method uses ``SESSION_KEY`` for saving request specific session info. + + +.. _aiohttp_faq_parallel_event_sources: + +How to receive an incoming events from different sources in parallel? +--------------------------------------------------------------------- + +For example we have two event sources: + + 1. WebSocket for event from end user + + 2. Redis PubSub from receiving events from other parts of app for + sending them to user via websocket. + +The most native way to perform it is creation of separate task for +pubsub handling. + +Parallel :meth:`aiohttp.web.WebSocketResponse.receive` calls are forbidden, only +the single task should perform websocket reading. + +But other tasks may use the same websocket object for sending data to +peer:: + + async def handler(request): + + ws = web.WebSocketResponse() + await ws.prepare(request) + task = request.app.loop.create_task( + read_subscription(ws, + request.app['redis'])) + try: + async for msg in ws: + # handle incoming messages + # use ws.send_str() to send data back + ... + + finally: + task.cancel() + + async def read_subscriptions(ws, redis): + channel, = await redis.subscribe('channel:1') + + try: + async for msg in channel.iter(): + answer = process message(msg) + ws.send_str(answer) + finally: + await redis.unsubscribe('channel:1') diff --git a/docs/web.rst b/docs/web.rst index e4ffea9422e..68d260bce04 100644 --- a/docs/web.rst +++ b/docs/web.rst @@ -552,6 +552,16 @@ incoming request. .. _SockJS: https://github.com/aio-libs/sockjs +.. warning:: + + Parallel reads from websocket are forbidden, there is no + possibility to call :meth:`aiohttp.web.WebSocketResponse.receive` + from two tasks. + + See :ref:`FAQ section ` for + instructions how to solve the problem. + + .. _aiohttp-web-exceptions: Exceptions