Both sides#
What does ConnectionClosedError: no close frame received or sent
mean?#
If you’re seeing this traceback in the logs of a server:
connection handler failed
Traceback (most recent call last):
...
asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 2 expected bytes
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
websockets.exceptions.ConnectionClosedError: no close frame received or sent
or if a client crashes with this traceback:
Traceback (most recent call last):
...
ConnectionResetError: [Errno 54] Connection reset by peer
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
websockets.exceptions.ConnectionClosedError: no close frame received or sent
it means that the TCP connection was lost. As a consequence, the WebSocket connection was closed without receiving and sending a close frame, which is abnormal.
You can catch and handle ConnectionClosed
to prevent it
from being logged.
There are several reasons why long-lived connections may be lost:
End-user devices tend to lose network connectivity often and unpredictably because they can move out of wireless network coverage, get unplugged from a wired network, enter airplane mode, be put to sleep, etc.
HTTP load balancers or proxies that aren’t configured for long-lived connections may terminate connections after a short amount of time, usually 30 seconds, despite websockets’ keepalive mechanism.
If you’re facing a reproducible issue, enable debug logs to see when and how connections are closed.
What does ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received
mean?#
If you’re seeing this traceback in the logs of a server:
connection handler failed
Traceback (most recent call last):
...
asyncio.exceptions.CancelledError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received
or if a client crashes with this traceback:
Traceback (most recent call last):
...
asyncio.exceptions.CancelledError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received
it means that the WebSocket connection suffered from excessive latency and was closed after reaching the timeout of websockets’ keepalive mechanism.
You can catch and handle ConnectionClosed
to prevent it
from being logged.
There are two main reasons why latency may increase:
Poor network connectivity.
More traffic than the recipient can handle.
See the discussion of timeouts for details.
If websockets’ default timeout of 20 seconds is too short for your use case,
you can adjust it with the ping_timeout
argument.
How do I set a timeout on recv()
?#
On Python ≥ 3.11, use asyncio.timeout()
:
async with asyncio.timeout(timeout=10):
message = await websocket.recv()
On older versions of Python, use asyncio.wait_for()
:
message = await asyncio.wait_for(websocket.recv(), timeout=10)
This technique works for most APIs. When it doesn’t, for example with
asynchronous context managers, websockets provides an open_timeout
argument.
How can I pass arguments to a custom protocol subclass?#
You can bind additional arguments to the protocol factory with
functools.partial()
:
import asyncio
import functools
import websockets
class MyServerProtocol(websockets.WebSocketServerProtocol):
def __init__(self, *args, extra_argument=None, **kwargs):
super().__init__(*args, **kwargs)
# do something with extra_argument
create_protocol = functools.partial(MyServerProtocol, extra_argument=42)
start_server = websockets.serve(..., create_protocol=create_protocol)
This example was for a server. The same pattern applies on a client.
How do I keep idle connections open?#
websockets sends pings at 20 seconds intervals to keep the connection open.
It closes the connection if it doesn’t get a pong within 20 seconds.
You can adjust this behavior with ping_interval
and ping_timeout
.
See Timeouts for details.
How do I respond to pings?#
If you are referring to Ping and Pong frames defined in the WebSocket protocol, don’t bother, because websockets handles them for you.
If you are connecting to a server that defines its own heartbeat at the application level, then you need to build that logic into your application.