Let's say that the WebSocket server is temporary down, and it drops incoming packets (rather than rejecting them)
Currently, it takes around 95 seconds between the connection attempt and the TimeoutError
I can't seem to find a way to reduce that window (so I can try another WebSocket server)
This is the demo code that I am running: (just taken from the official docs
#!/usr/bin/env python
import asyncio
import websockets
import os
import socket
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s [%(name)s.%(funcName)s:%(lineno)d]: %(message)s', datefmt='%m-%d %H:%M:%S', )
host = os.environ.get('SERVER_URL','localhost:9090')
self_id = os.environ.get('SELF_ID',socket.gethostname())
connect_url =f'ws://{host}/{self_id}'
logging.info(f'Connect to: {connect_url}')
async def hello(uri):
logging.info(f'Connecting to {uri}')
async with websockets.connect(uri, timeout=1, close_timeout=1) as websocket:
logging.info(f"Conected to {uri}")
async for message in websocket:
await websocket.send(message)
asyncio.get_event_loop().run_until_complete(
hello(connect_url))
The websocket-idle-timeout command sets the maximum idle time for client connections with the handler. This timer monitors the idle time in the data transfer process. If the specified idle time is exceeded, the connection is torn down.
Send a heart-beat or ping In order to keep the session alive, the client could keep sending a heart-beat or a ping to the server. The retry decorator, every time there is WebSocketConnectionClosedException, reconnects to the WebSocket server in a delay of 2 seconds, keeping the session alive.
In python websockets, you can use "ws. keep_running = False" to stop the "forever running" websocket.
When I form a WebSocket with a browser (without any ping messages), the connection with the server lasts at least 12 hours (which is as much I've tested). But with your Python WebSocket client, it seems to disconnect at 31 minutes, 13 seconds.
Fortunately, Python gives you a chance to set up socket timeout for all new sockets, which will be created during application work: import socket socket.setdefaulttimeout (10) sock = socket.socket ()
The WebSocket protocol provides full-duplex communication channels over a single TCP connection. After the initial handshake, it allows for two way data transfer between client and server, and this with lower overhead than polling alternatives. Applied to our use case the client would first setup a WebSocket connection to the server.
The connect () operation is also subject to the timeout setting, and in general it is recommended to call settimeout () before calling connect () or pass a timeout parameter to create_connection (). However, the system network stack may also return a connection timeout error of its own regardless of any Python socket timeout setting.
You can use asyncio's wait_for() like this:
import asyncio
from concurrent.futures import TimeoutError as ConnectionTimeoutError
# whatever url is your websocket server
url = 'ws://localhost:9090'
# timeout in seconds
timeout = 10
try:
# make connection attempt
connection = await asyncio.wait_for(websockets.connect(url), timeout)
except ConnectionTimeoutError as e:
# handle error
print('Error connecting.')
It will raise a <class 'concurrent.futures._base.TimeoutError'>
exception which can be caught with the except ConnectionTimeoutError
block.
In python3.8 it raises a TimeoutError
which can be caught with the except asyncio.exceptions.TimeoutError
block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With