Как совместить python веб-сокеты и другие асинхронные задачи - PullRequest
1 голос
/ 27 апреля 2020

У меня есть большое приложение python (теперь преобразованное в python3), в котором основной код работал бесконечно l oop.

while (True):
      #Do loads of stuff, connect to rs485 devices, obtain their status etc.

Я хочу использовать веб-сокеты с этим приложением. Я теперь преобразовал это так, чтобы структура была:

def mainPoll():
    #Do loads of stuff (omitted for brevity)

while (True):
     mainPoll()

Пример кода websockets (от ЗДЕСЬ ), который я имею в качестве отправной точки:

import asyncio
import datetime
import random
import websockets
async def time(websocket, path):
    while True:
        now = datetime.datetime.utcnow().isoformat() + "Z"
        await websocket.send(now)
        await asyncio.sleep(random.random() * 3)

start_server = websockets.serve(time, "127.0.0.1", 5678)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

Редактировать Я пытался объединить два. Mycode ниже будет запускать mainPoll () асинхронно один раз с использованием create_task. Есть ли лучший способ продолжить работу, если снова вызвать create_task в конце mainPoll ?

async def mainPoll():
     #do loads of stuff (omitted for brevity)
     #then create another task to run myself again?!?!?!
     #IS THIS NEXT LINE THE BEST WAY?
     asyncio.get_event_loop().create_task(mainPoll())
     #end of mainPoll

async def xtime(websocket, path):
    while True:
        now = str(time.time())
        await websocket.send(now)
        await asyncio.sleep(random.random() * 3)

start_server = websockets.serve(xtime, "0.0.0.0", 5678)
asyncio.get_event_loop().run_until_complete(start_server)
poll=asyncio.get_event_loop().create_task(mainPoll())
asyncio.get_event_loop().run_forever()

Я бы очень признателен за некоторые указатели здесь, поскольку код websockets не кажется чтобы соответствовать любому из примеров asyncio, которые я могу найти. Большое спасибо.

1 Ответ

1 голос
/ 28 апреля 2020

mainPoll должна быть асинхронной c функцией. Нет необходимости заново создавать задачу, как показано в вопросе - вполне нормально, чтобы она содержала while True l oop, если в l oop что-то ожидается. Если вам нужны там блокирующие API, используйте run_in_executor, чтобы ожидать их, не мешая веб-сокетам.

...