Python websockets keepalive ping timeout; no close frame received

Question:

I have 20-50 users from whom I want real-time information about whether they are connected to the Internet or have a weak Internet

I wrote a Python script that checks the connection and sends the information to the web server in Django django-channels
script run in the Windows scheduler from 9 am to 6 pm

Script

    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 pack: https://websockets.readthedocs.io/

Send information ping min, max, avg every 30 seconds
And make sure that the client is connected as long as it is connected to the server

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
        .......

The problem is that python script occasionally locks up with the message

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

no close frame received or sent

and I can’t call back automatic

How can I keep the connection open or if it closes it reopens in a small percentage of time so that the front end cannot modify online or offline indicator

Asked By: Elabbasy00

||

Answers:

I ended up reconnecting with something like this

 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)

But I had one problem which was adjusting the user state on every connection. In this case, you can use this blog and this answer to lighten the load on the database

Answered By: Elabbasy00
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.