Я сделал фиктивный сервер для проверки моего приложения websockets.Он прослушивает subscription
сообщения, затем выдает информацию об этих подписках через сокет.
Атрибут класса 'subscriptions
пуст при инициализации и должен заполняться, поскольку функция listen()
получает сообщения подписки.Однако кажется, что self.subscriptions
в talk()
никогда не добавляется, оставляя его застрявшим в бесконечном цикле while и никогда не передавая сообщения.
Проблема решается добавлением строки await asyncio.sleep(1)
последля цикла.Но почему?Разве self.subscriptions
не следует пересматривать каждый раз при запуске цикла for?
Код ниже:
class DummyServer:
def __init__(self):
self.subscriptions = []
def start(self):
return websockets.serve(self.handle, 'localhost', 8765)
async def handle(self, websocket, path):
self.ws = websocket
listen_task = asyncio.ensure_future(self.listen())
talk_task = asyncio.ensure_future(self.talk())
done, pending = await asyncio.wait(
[listen_task, talk_task],
return_when=asyncio.FIRST_COMPLETED
)
for task in pending:
task.cancel()
async def listen(self):
while True:
try:
msg = await self.ws.recv()
msg = json.loads(msg)
await self.triage(msg) # handles subscriptions
except Exception as e:
await self.close()
break
async def talk(self):
while True:
for s in self.subscriptions:
dummy_data = {
'product_id': s
}
try:
await self.send(json.dumps(dummy_data))
except Exception as e:
await self.close()
break
await asyncio.sleep(1) # without this line, no message is ever sent