Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python websockets, how to setup connect timeout

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))
like image 840
SimSimY Avatar asked Jan 29 '19 12:01

SimSimY


People also ask

Does WebSocket have timeout?

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.

How do you keep a WebSocket connection alive in Python?

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.

How do I stop a WebSocket connection in Python?

In python websockets, you can use "ws. keep_running = False" to stop the "forever running" websocket.

How long does a Python WebSocket connection with a server last?

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.

How do I set socket timeout in Python?

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

What is the WebSocket protocol?

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.

How to fix a connection timeout error in Python?

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.


1 Answers

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.

like image 168
Joules Avatar answered Sep 30 '22 08:09

Joules