Уведомления

Группа в Telegram: @pythonsu

#1 Май 23, 2022 07:39:44

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Вставить в асинхронный цикл код, чтобы он работал по времени

Добрый день. Задача такая: есть асинхронная фунция, в которой идет работа с websocket. Сначала рукопожатие, потом отправка необходимых данных. В цикле осуществляется ожидание данных. Но для сохранения коннекта нужно посылать каждые 5 сек пинг вне зависимости от прихода данных. Т.е. в основном цикле должен быть еще один безконечный цикл, в котором через 5 сек будет посылаться пинг и этот вложенный цикл должен жить отдельной жизнью от основного цикла. Подскажите, пожалуйста, как это можно сделать? Спасибо.

 async def run_websockets():
    uri = "wss://site.ru/socket.io/?EIO=3&transport=websocket"
    async with websockets.connect(uri, subprotocols=["websocket"], extra_headers=extra_headers) as ws:
        greeting = await ws.recv()
        print(f'greeting >>> {greeting}')
        print('=== greeting ===')
        message = await ws.recv()
        await ws.send("broadcast1")
        await ws.send("observer2")
        message = await ws.recv()
        # в этом цикле необходимо реализовать идею с пингом
        while True:
            try:
                message = await ws.recv()
            except websockets.exceptions.ConnectionClosedError:
                print('*** ConnectionClosedError ***')

Офлайн

#2 Май 29, 2022 01:46:06

DamMercul
Зарегистрирован: 2017-11-26
Сообщения: 325
Репутация: +  13  -
Профиль   Отправить e-mail  

Вставить в асинхронный цикл код, чтобы он работал по времени

Можешь отдельно сделать поток, который будет обособлен от основного цикла и самостоятельно посылать сообщения:

 from threading import Thread
from time import sleep
THREAD_STATUS = True
def keepalive(connection):
    while THREAD_STATUS:
        connection.send(b"XXX")
        sleep(5)
Не работал с вебсокетами особо, модуля не знаю, но внутри await подключи этот поток и дай ему соединение в аргументах, а когда основной цикл завершится, то THREAD_STATUS сделай False, и поток умрет



____________________________________________________

 # Life loop
while alive:
    if (fun > boredom) and money:
        pass_day(fun, boredom, money)
        continue
    else: break

Офлайн

#3 Май 29, 2022 10:24:15

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  252  -
Профиль   Отправить e-mail  

Вставить в асинхронный цикл код, чтобы он работал по времени

DamMercul
Можешь отдельно сделать поток, который будет обособлен от основного цикла
Конечно можно… Но это так не асинхронно!!! Выглядит как скрещивание ужа с ежом.
Во первых для пинга лучше дождаться соединения. “async with websockets.connect” , создать асинхронную задачу
примерно вот такую https://docs.python.org/3/library/asyncio-task.html#sleeping
, и поставить ее на выполнение
https://docs.python.org/3/library/asyncio-future.html#asyncio.ensure_future
.
Очевидно при закрытии соединения надо задачу пинга завершить https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel.



Отредактировано doza_and (Май 29, 2022 10:25:57)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version