Home > database >  How to run an asyncio/websockets server in a separate thread: ERROR: -> There is no current event
How to run an asyncio/websockets server in a separate thread: ERROR: -> There is no current event

Time:06-12

I am trying to add web-socket functionality (to respond to some occasional inbound web-socket based requests) to an existing small python desktop app that is already doing other things. It already has a couple of threads running performing various tasks.

I have found and reviewed a few STACK articles that are similar to my issue here, and sadly, I'm pretty novice to async in python. I haven't been able to create a solution based on the other articles.

Here is one of those similar articles: Asyncio websocket in separate thread

I was unable to get such a solution to work for me.

Here is my simple code that fails:

# asamp.py
import time
import datetime
import asyncio
import websockets
import threading

def bgWorker_SK():
    # create handler for each connection
    async def handler(websocket, path):
        data = await websocket.recv()
        reply = f"Data recieved as:  {data}!"
        await websocket.send(reply)
        
    start_server = websockets.serve(handler, "localhost", 5564)
    asyncio.loop.run_until_complete(start_server)
    asyncio.loop.run_forever()

bgsk = threading.Thread(target=bgWorker_SK, daemon=True).start() 


if __name__ == '__main__':  
    
    # the main is off busy doing something other work...
    # trivial example here
    while True:        
        print (datetime.datetime.now())
        time.sleep(2)

The above, generates the error in Python 3.8.10:

builtins.RuntimeError: There is no current event loop in thread 'Thread-1'.

Please help :-{

CodePudding user response:

Try:

# asamp.py
import time
import datetime
import asyncio
import websockets
import threading


def bgWorker_SK():
    # create handler for each connection
    async def handler(websocket, path):
        data = await websocket.recv()
        reply = f"Data recieved as:  {data}!"
        await websocket.send(reply)

    loop = asyncio.new_event_loop()   # <-- create new loop in this thread here
    asyncio.set_event_loop(loop)

    start_server = websockets.serve(handler, "localhost", 5564)
    loop.run_until_complete(start_server)
    loop.run_forever()


bgsk = threading.Thread(target=bgWorker_SK, daemon=True).start()


if __name__ == "__main__":
    # the main is off busy doing something other work...
    # trivial example here
    while True:
        print(datetime.datetime.now())
        time.sleep(2)

This opens new TCP port on localhost:5564 and starts listening on it.

  • Related