#python #loops #websocket #async-await
#python #циклы #веб-сокет #асинхронное ожидание
Вопрос:
Новичок в python. Я пытаюсь заставить что-то работать, и я не знаю, правильна ли моя логика.
Итак, у меня есть weksocket (ws), для того, чтобы этот веб-сокет оставался подключенным, требуется каждая минута, когда он получает «ping», я должен ответить «pong:
Итак, я сделал что-то вроде этого:
async def run():
prepare_env("test")
async with websockets.connect(wss_request_url, ssl=True) as ws:
while True:
msg = await ws.recv()
if msg == "ping":
print("received: ping")
await send(ws, "pong")
else:
response = json.loads(msg)
if "something" in response:
await handle_message(ws, response)
else:
print(f"received:{response}")
asyncio.get_event_loop().run_until_complete(run())
На основе «чего-то» в ответе у меня есть в какой-то момент функция (verify_price), которую необходимо проверить в rest API при изменении цены.
async def verify_price(ws, old_price):
price_changed = False
while price_changed is False:
price = get_new_price()
if price <> old_price:
await send(ws, "pricechanged")
price_changed = True
Моя проблема в том, что, пока я нахожусь внутри этого цикла while, ожидая изменения цены, если я получу еще один пинг, он не ответит с помощью pong и отключит мое соединение.
Тай, Дэнни
Комментарии:
1. «пока я нахожусь внутри этого цикла, если я получу еще один пинг, он не ответит с помощью pong» — вам нужно запустить цикл проверки цен в своем собственном потоке. Основной поток должен отвечать за прослушивание сокета и отправку задач рабочим потокам.
2. Даже «ответ с помощью pong» должен быть задачей другого потока. Ваш основной цикл должен помещать рабочие задания только в конец очереди и возвращаться к прослушиванию как можно быстрее, в то время как пул рабочих потоков продолжает выбирать рабочие задания из начала очереди и выполнять их.
3. … и поскольку у вас не может быть неограниченных потоков, но ожидание изменения цены может занять неограниченное время, создание цикла «пока цена не изменилась» приведет к возможности DOS. Если у вас есть 10 рабочих и поступает 10 запросов «проверить цену», ваша служба больше не будет отвечать, потому что все 10 рабочих потоков будут находиться в цикле занятости, ожидая. Поэтому проверки цен должны быть отдельными задачами в основной рабочей очереди. Если цена не изменилась, рабочий поток должен поместить другую задачу «проверить цену» в конец очереди вместо того, чтобы переходить в сам цикл.
4. … и (последнее замечание) поскольку 10 входящих запросов на проверку цен могут быть для одного и того же товара, и вы не хотите, чтобы ваши рабочие потоки впадали в безумие, параллельно проверяя один и тот же товар, вам нужен реестр того, над чем вы работаете, чтобы повторяющиеся запросы не приводили кповторяющаяся проверка, только для дублирования ответов (т. Е.: «Клиент A, B и C запросили X. Давайте сделаем X один раз, и как только X будет выполнено, уведомите A, B и C.» )
5. @user2260630 В качестве альтернативы вы можете поделиться написанным вами кодом для решения вашей проблемы в своем собственном ответе. Отвечая на ваш собственный вопрос, рекомендуется использовать Stack Overflow, вы можете помочь кому-то другому научиться этому.