Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Asyncio within a thread
#1
I'm new to asyncio and I'm trying to understand how to incorporate it into a thread.

What I need to do is add a web server with websockets into an existing application. That is, the existing application will continue to function as it already does, but additionally, a web server will run in a separate thread providing access to some of the data from the application via a web browser, and also periodically pushing data to the web browser via web sockets. All the examples I can find seem to assume that the web server is the only thing that the entire application needs to do.

I have a very simple test application below, based on the example in the docs as well as the best write-up on asyncio I have found so far. It has a couple of issues:
  1. It doesn't terminate cleanly ("Task was destroyed but it is pending!") when I kill the script via Ctrl-C
  2. I can't see how to push data into the thread's loop

Am I heading in completely the wrong direction, or am I close?

import asyncio
import threading
from aiohttp import web
import time

async def wshandler(request):
    ws = web.WebSocketResponse()
    await ws.prepare(request)

    async for msg in ws:
        if msg.type == web.MsgType.text:
            x = "Hello, {}".format(msg.data)
            print(x)
            await ws.send_str(x)
        elif msg.type == web.MsgType.binary:
            await ws.send_bytes(msg.data)
        elif msg.type == web.MsgType.close:
            break

    return ws

async def handler(request):
    name = request.match_info.get('name', "Anonymous")
    text = "Hello, " + name
    return web.Response(text=text)

async def init(loop):
    global srv
    app = web.Application(loop=loop)
    app.router.add_get('/ws', wshandler)
    app.router.add_get('/', handler)
    app.router.add_get('/{name}', handler)

    srv = await loop.create_server(app.make_handler(),
                                        '0.0.0.0', 8080)
    print("Server started at http://127.0.0.1:8080")
    return srv

def test(loop):
    loop.run_until_complete(init(loop))
    loop.run_forever()

loop = asyncio.new_event_loop()
t = threading.Thread(target=test,args=(loop,))
try:
    t.start()
    while True:
        print('.', end='', flush=True)
        time.sleep(1)

except KeyboardInterrupt:
    loop.stop()
Reply
#2
except KeyboardInterrupt:
    loop.stop()
    loop.close()
Does this work?
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#3
(Mar-09-2018, 07:03 PM)wavic Wrote:
except KeyboardInterrupt:
    loop.stop()
    loop.close()
Does this work?

Error:
RuntimeError: Cannot close a running event loop asyncio: Task was destroyed but it is pending!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Error SQLite objects created in a thread can only be used in that same thread. binhduonggttn 3 15,393 Jan-31-2020, 11:08 AM
Last Post: DeaD_EyE
  how this to make a asyncio thread safe? linziyan 0 2,328 Jun-07-2018, 10:33 AM
Last Post: linziyan

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020