Python websockets keepalive ping timeout; close frame не получен

У меня есть 20-50 пользователей, от которых мне нужна информация в реальном времени о том, подключены ли они к Интернету или имеют слабый Интернет

Я написал скрипт на Python, который проверяет соединение и отправляет информацию на веб-сервер в Django django-channels скрипт запускается в планировщике Windows с 9 утра до 6 вечера

Сценарий

    async def main():
        username = get_username()
        url = "{}{}/".format(LOG_SERVER, username)
        async with websockets.connect(url) as websocket:
            # send info to server
            while True:
                try:
                    loop = asyncio.get_event_loop()
                    data = await loop.run_in_executor(None, 
                                              lambda:get_data(username))
                    await websocket.send(json.dumps(data))
                    await asyncio.sleep(30)
                except websockets.ConnectionClosed as e:
                    print(f'Terminated', e)
                    continue
                except Exception as e:
                    logging.error(e)

if __name__ == "__main__":
    asyncio.run(main())

Пакет WebSockets: https://websockets.readthedocs.io/

Отправляйте информацию ping min, max, avg каждые 30 секунд. И убедитесь, что клиент подключен до тех пор, пока он подключен к серверу

Django Consumer

async def connect(self):
        try:
            self.username = self.scope['url_route']['kwargs']['username']
            await database_sync_to_async(self.update_user_incr)(self.username)
        except KeyError as e:
            pass
          ......
async def disconnect(self, close_code):
     
        try:
            if(self.username):
                await database_sync_to_async(self.update_user_decr)(self.username)
        except:
            pass
        .......

Проблема в том, что скрипт python иногда блокируется с сообщением

sent 1011 (unexpected error) keepalive ping timeout; no close frame received

no close frame received or sent

и я не могу перезвонить автоматически

Как я могу держать соединение открытым или если оно закрывается, то снова открывается через небольшой процент времени, чтобы фронт-энд не мог изменять индикатор онлайн или офлайн

В итоге я воссоединился с чем-то подобным

 async for websocket in websockets.connect(url):
        try:
            loop = asyncio.get_event_loop()
            data = await loop.run_in_executor(None, lambda: get_data(username))
            await websocket.send(json.dumps(data))
            await asyncio.sleep(30)
        except websockets.ConnectionClosed as e:
            print(f'Terminated', e)

Но у меня была одна проблема, которая заключалась в корректировке состояния пользователя при каждом подключении. В этом случае вы можете использовать этот blog и этот answer для облегчения нагрузки на базу данных

Вернуться на верх