Ошибка выполнения Python: этот цикл событий уже запущен

#python #python-3.x #websocket #python-asyncio

#python #python-3.x #websocket #python-asyncio

Вопрос:

Это очень распространенная проблема, но на самом деле я не могу найти на нее правильный ответ. У меня есть следующий код для подключения к серверу через websocket, и я хочу сохранить его в рабочем состоянии и продолжать прослушивать отправляемые им сообщения, как показано ниже:

 import asyncio
import websockets
import nest_asyncio
nest_asyncio.apply()
            
async def listen_for_message(websocket):
    while True:
        await asyncio.sleep(0)
        message = await websocket.recv()
        print(message)

async def connect_to_dealer():
    websocket = await websockets.connect(websocketadress)

    hello_message = await websocket.recv()
    print(hello_message)

async def my_app():
    websocket = await connect_to_dealer()
    asyncio.ensure_future(listen_for_message(websocket))

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(my_app())
    loop.run_forever()
  

И это вызывает ошибку:

   File "untitled0.py", line 71, in <module>
    loop.run_forever()
  File "Anaconda3libasynciobase_events.py", line 525, in run_forever
    raise RuntimeError('This event loop is already running') 
RuntimeError: This event loop is already running
  

И без

 import nest_asyncio
nest_asyncio.apply()
  

Я получаю:

   File "untitled0.py", line 70, in <module>
    loop.run_until_complete(my_app()) 
  File "Anaconda3libasynciobase_events.py", line 570, in run_until_complete
    self.run_forever()
  File "Anaconda3libasynciobase_events.py", line 525, in run_forever
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
  

Я все еще не понимаю, почему он это делает.

Ответ №1:

loop.run_until_complete() ваш цикл уже выполняется «навсегда».

Вместо того, чтобы запускать ваш listen_for_message() awaitable как задачу, просто ожидайте его. Затем он выполняется вечно, потому что listen_for_message() сам по себе никогда не возвращается:

 async def my_app():
    websocket = await connect_to_dealer()
    await listen_for_message(websocket)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(my_app())
  

Обратите внимание, что ваша connect_to_dealer() функция не возвращает websocket; вероятно, это упущение, которое вы хотите исправить:

 async def connect_to_dealer():
    return await websockets.connect(websocketadress)
  

Я удалил там строки hello_message = await websocket.recv() / print(hello_message) , потому что listen_for_message() они уже будут получать сообщения и печатать их.