common.rst (5688B)
1 Both sides 2 ========== 3 4 .. currentmodule:: websockets 5 6 What does ``ConnectionClosedError: no close frame received or sent`` mean? 7 -------------------------------------------------------------------------- 8 9 If you're seeing this traceback in the logs of a server: 10 11 .. code-block:: pytb 12 13 connection handler failed 14 Traceback (most recent call last): 15 ... 16 asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 2 expected bytes 17 18 The above exception was the direct cause of the following exception: 19 20 Traceback (most recent call last): 21 ... 22 websockets.exceptions.ConnectionClosedError: no close frame received or sent 23 24 or if a client crashes with this traceback: 25 26 .. code-block:: pytb 27 28 Traceback (most recent call last): 29 ... 30 ConnectionResetError: [Errno 54] Connection reset by peer 31 32 The above exception was the direct cause of the following exception: 33 34 Traceback (most recent call last): 35 ... 36 websockets.exceptions.ConnectionClosedError: no close frame received or sent 37 38 it means that the TCP connection was lost. As a consequence, the WebSocket 39 connection was closed without receiving and sending a close frame, which is 40 abnormal. 41 42 You can catch and handle :exc:`~exceptions.ConnectionClosed` to prevent it 43 from being logged. 44 45 There are several reasons why long-lived connections may be lost: 46 47 * End-user devices tend to lose network connectivity often and unpredictably 48 because they can move out of wireless network coverage, get unplugged from 49 a wired network, enter airplane mode, be put to sleep, etc. 50 * HTTP load balancers or proxies that aren't configured for long-lived 51 connections may terminate connections after a short amount of time, usually 52 30 seconds, despite websockets' keepalive mechanism. 53 54 If you're facing a reproducible issue, :ref:`enable debug logs <debugging>` to 55 see when and how connections are closed. 56 57 What does ``ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received`` mean? 58 --------------------------------------------------------------------------------------------------------------------- 59 60 If you're seeing this traceback in the logs of a server: 61 62 .. code-block:: pytb 63 64 connection handler failed 65 Traceback (most recent call last): 66 ... 67 asyncio.exceptions.CancelledError 68 69 The above exception was the direct cause of the following exception: 70 71 Traceback (most recent call last): 72 ... 73 websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received 74 75 or if a client crashes with this traceback: 76 77 .. code-block:: pytb 78 79 Traceback (most recent call last): 80 ... 81 asyncio.exceptions.CancelledError 82 83 The above exception was the direct cause of the following exception: 84 85 Traceback (most recent call last): 86 ... 87 websockets.exceptions.ConnectionClosedError: sent 1011 (internal error) keepalive ping timeout; no close frame received 88 89 it means that the WebSocket connection suffered from excessive latency and was 90 closed after reaching the timeout of websockets' keepalive mechanism. 91 92 You can catch and handle :exc:`~exceptions.ConnectionClosed` to prevent it 93 from being logged. 94 95 There are two main reasons why latency may increase: 96 97 * Poor network connectivity. 98 * More traffic than the recipient can handle. 99 100 See the discussion of :doc:`timeouts <../topics/timeouts>` for details. 101 102 If websockets' default timeout of 20 seconds is too short for your use case, 103 you can adjust it with the ``ping_timeout`` argument. 104 105 How do I set a timeout on :meth:`~legacy.protocol.WebSocketCommonProtocol.recv`? 106 -------------------------------------------------------------------------------- 107 108 On Python ≥ 3.11, use :func:`asyncio.timeout`:: 109 110 async with asyncio.timeout(timeout=10): 111 message = await websocket.recv() 112 113 On older versions of Python, use :func:`asyncio.wait_for`:: 114 115 message = await asyncio.wait_for(websocket.recv(), timeout=10) 116 117 This technique works for most APIs. When it doesn't, for example with 118 asynchronous context managers, websockets provides an ``open_timeout`` argument. 119 120 How can I pass arguments to a custom protocol subclass? 121 ------------------------------------------------------- 122 123 You can bind additional arguments to the protocol factory with 124 :func:`functools.partial`:: 125 126 import asyncio 127 import functools 128 import websockets 129 130 class MyServerProtocol(websockets.WebSocketServerProtocol): 131 def __init__(self, *args, extra_argument=None, **kwargs): 132 super().__init__(*args, **kwargs) 133 # do something with extra_argument 134 135 create_protocol = functools.partial(MyServerProtocol, extra_argument=42) 136 start_server = websockets.serve(..., create_protocol=create_protocol) 137 138 This example was for a server. The same pattern applies on a client. 139 140 How do I keep idle connections open? 141 ------------------------------------ 142 143 websockets sends pings at 20 seconds intervals to keep the connection open. 144 145 It closes the connection if it doesn't get a pong within 20 seconds. 146 147 You can adjust this behavior with ``ping_interval`` and ``ping_timeout``. 148 149 See :doc:`../topics/timeouts` for details. 150 151 How do I respond to pings? 152 -------------------------- 153 154 If you are referring to Ping_ and Pong_ frames defined in the WebSocket 155 protocol, don't bother, because websockets handles them for you. 156 157 .. _Ping: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.2 158 .. _Pong: https://www.rfc-editor.org/rfc/rfc6455.html#section-5.5.3 159 160 If you are connecting to a server that defines its own heartbeat at the 161 application level, then you need to build that logic into your application.