У меня есть встроенный сервер Python, который использует Sani c и веб-сокеты для обычной передачи данных клиентам:
@app.websocket("/")
async def websocket(request, ws):
app.ws_clients.add(ws)
await ws.send(json.dumps("hello from climate server!"))
while True:
try:
data = dict()
time_of_reading = time.ctime(time.time())
data['climateData'] = sensor.read_data()
data['systemData'] = get_system_data()
data['timestamp'] = time_of_reading
await broadcast(json.dumps(data))
time.sleep(10) # changing this to asyncio.sleep() causes the msgs to send sporatically
except KeyboardInterrupt:
sensor.clear()
pass
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, workers=1, debug=False)
и мою функцию широковещания, которая пытается отправить сообщение или удаляет клиент из app.ws_clients
, если есть ошибка ConnectionClosed
:
async def broadcast(message):
for ws in app.ws_clients:
try:
await ws.send(message)
print('attempting data send') # this line runs, but the clients don't receive the messages
except websockets.ConnectionClosed:
clients_to_remove.add(ws)
except KeyboardInterrupt:
sensor.clear()
pass
if (len(clients_to_remove) > 0):
await remove_dead_clients(clients_to_remove)
async def remove_dead_clients(clients_to_remove):
for client in clients_to_remove:
app.ws_clients.remove(client)
clients_to_remove.clear()
Клиент может подключиться очень хорошо, и сервер печатает, что он пытается передать, но сообщение не получено клиент.
Я использую эту функцию широковещания с другого сервера, который я написал, и она прекрасно работает там. Разница с этим в том, что он отправляет данные только тогда, когда клиент запрашивает их. Я чувствую, что проблема в том, что asyn c не может одновременно обрабатывать и удалять клиентов. Я попытался изменить time.sleep()
на asyncio.sleep()
, но это позволило только успешно отправлять сообщения десятки за раз, а потом вообще ничего не делать.
Есть ли шаблон, который я мог бы реализовать, который бы соответствовал моим нужно, куда я могу отправлять сообщения в бесконечном l oop, а также асинхронно управлять подключенными клиентами?