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