Both sides (asyncio
)#
- class websockets.legacy.protocol.WebSocketCommonProtocol(*, logger=None, ping_interval=20, ping_timeout=20, close_timeout=10, max_size=2**20, max_queue=2**5, read_limit=2**16, write_limit=2**16)[source]#
WebSocket connection.
WebSocketCommonProtocol
provides APIs shared between WebSocket servers and clients. You shouldn’t use it directly. Instead, useWebSocketClientProtocol
orWebSocketServerProtocol
.This documentation focuses on low-level details that aren’t covered in the documentation of
WebSocketClientProtocol
andWebSocketServerProtocol
for the sake of simplicity.Once the connection is open, a Ping frame is sent every
ping_interval
seconds. This serves as a keepalive. It helps keeping the connection open, especially in the presence of proxies with short timeouts on inactive connections. Setping_interval
toNone
to disable this behavior.If the corresponding Pong frame isn’t received within
ping_timeout
seconds, the connection is considered unusable and is closed with code 1011. This ensures that the remote endpoint remains responsive. Setping_timeout
toNone
to disable this behavior.See the discussion of timeouts for details.
The
close_timeout
parameter defines a maximum wait time for completing the closing handshake and terminating the TCP connection. For legacy reasons,close()
completes in at most5 * close_timeout
seconds for clients and4 * close_timeout
for servers.close_timeout
is a parameter of the protocol because websockets usually callsclose()
implicitly upon exit:on the client side, when using
connect()
as a context manager;on the server side, when the connection handler terminates.
To apply a timeout to any other API, wrap it in
timeout()
orwait_for()
.The
max_size
parameter enforces the maximum size for incoming messages in bytes. The default value is 1 MiB. If a larger message is received,recv()
will raiseConnectionClosedError
and the connection will be closed with code 1009.The
max_queue
parameter sets the maximum length of the queue that holds incoming messages. The default value is32
. Messages are added to an in-memory queue when they’re received; thenrecv()
pops from that queue. In order to prevent excessive memory consumption when messages are received faster than they can be processed, the queue must be bounded. If the queue fills up, the protocol stops processing incoming data untilrecv()
is called. In this situation, various receive buffers (at least inasyncio
and in the OS) will fill up, then the TCP receive window will shrink, slowing down transmission to avoid packet loss.Since Python can use up to 4 bytes of memory to represent a single character, each connection may use up to
4 * max_size * max_queue
bytes of memory to store incoming messages. By default, this is 128 MiB. You may want to lower the limits, depending on your application’s requirements.The
read_limit
argument sets the high-water limit of the buffer for incoming bytes. The low-water limit is half the high-water limit. The default value is 64 KiB, half of asyncio’s default (based on the current implementation ofStreamReader
).The
write_limit
argument sets the high-water limit of the buffer for outgoing bytes. The low-water limit is a quarter of the high-water limit. The default value is 64 KiB, equal to asyncio’s default (based on the current implementation ofFlowControlMixin
).See the discussion of memory usage for details.
- Parameters:
logger (Optional[LoggerLike]) – Logger for this server. It defaults to
logging.getLogger("websockets.protocol")
. See the logging guide for details.ping_interval (Optional[float]) – Delay between keepalive pings in seconds.
None
disables keepalive pings.ping_timeout (Optional[float]) – Timeout for keepalive pings in seconds.
None
disables timeouts.close_timeout (Optional[float]) – Timeout for closing the connection in seconds. For legacy reasons, the actual timeout is 4 or 5 times larger.
max_size (Optional[int]) – Maximum size of incoming messages in bytes.
None
disables the limit.max_queue (Optional[int]) – Maximum number of incoming messages in receive buffer.
None
disables the limit.read_limit (int) – High-water mark of read buffer in bytes.
write_limit (int) – High-water mark of write buffer in bytes.
- await recv()[source]#
Receive the next message.
When the connection is closed,
recv()
raisesConnectionClosed
. Specifically, it raisesConnectionClosedOK
after a normal connection closure andConnectionClosedError
after a protocol error or a network failure. This is how you detect the end of the message stream.Canceling
recv()
is safe. There’s no risk of losing the next message. The next invocation ofrecv()
will return it.This makes it possible to enforce a timeout by wrapping
recv()
intimeout()
orwait_for()
.- Returns:
A string (
str
) for a Text frame. A bytestring (bytes
) for a Binary frame.- Return type:
- Raises:
ConnectionClosed – When the connection is closed.
RuntimeError – If two coroutines call
recv()
concurrently.
- await send(message)[source]#
Send a message.
A string (
str
) is sent as a Text frame. A bytestring or bytes-like object (bytes
,bytearray
, ormemoryview
) is sent as a Binary frame.send()
also accepts an iterable or an asynchronous iterable of strings, bytestrings, or bytes-like objects to enable fragmentation. Each item is treated as a message fragment and sent in its own frame. All items must be of the same type, or elsesend()
will raise aTypeError
and the connection will be closed.send()
rejects dict-like objects because this is often an error. (If you want to send the keys of a dict-like object as fragments, call itskeys()
method and pass the result tosend()
.)Canceling
send()
is discouraged. Instead, you should close the connection withclose()
. Indeed, there are only two situations wheresend()
may yield control to the event loop and then get canceled; in both cases,close()
has the same effect and is more clear:The write buffer is full. If you don’t want to wait until enough data is sent, your only alternative is to close the connection.
close()
will likely time out then abort the TCP connection.message
is an asynchronous iterator that yields control. Stopping in the middle of a fragmented message will cause a protocol error and the connection will be closed.
When the connection is closed,
send()
raisesConnectionClosed
. Specifically, it raisesConnectionClosedOK
after a normal connection closure andConnectionClosedError
after a protocol error or a network failure.- Parameters:
message (Union[Data, Iterable[Data], AsyncIterable[Data]) – message to send.
- Raises:
ConnectionClosed – When the connection is closed.
TypeError – If
message
doesn’t have a supported type.
- await close(code=CloseCode.NORMAL_CLOSURE, reason='')[source]#
Perform the closing handshake.
close()
waits for the other end to complete the handshake and for the TCP connection to terminate. As a consequence, there’s no need to awaitwait_closed()
afterclose()
.close()
is idempotent: it doesn’t do anything once the connection is closed.Wrapping
close()
increate_task()
is safe, given that errors during connection termination aren’t particularly useful.Canceling
close()
is discouraged. If it takes too long, you can set a shorterclose_timeout
. If you don’t want to wait, let the Python process exit, then the OS will take care of closing the TCP connection.
- await wait_closed()[source]#
Wait until the connection is closed.
This coroutine is identical to the
closed
attribute, except it can be awaited.This can make it easier to detect connection termination, regardless of its cause, in tasks that interact with the WebSocket connection.
- await ping(data=None)[source]#
Send a Ping.
A ping may serve as a keepalive, as a check that the remote endpoint received all messages up to this point, or to measure
latency
.Canceling
ping()
is discouraged. Ifping()
doesn’t return immediately, it means the write buffer is full. If you don’t want to wait, you should close the connection.Canceling the
Future
returned byping()
has no effect.- Parameters:
data (Optional[Data]) – payload of the ping; a string will be encoded to UTF-8; or
None
to generate a payload containing four random bytes.- Returns:
A future that will be completed when the corresponding pong is received. You can ignore it if you don’t intend to wait. The result of the future is the latency of the connection in seconds.
pong_waiter = await ws.ping() # only if you want to wait for the corresponding pong latency = await pong_waiter
- Return type:
- Raises:
ConnectionClosed – When the connection is closed.
RuntimeError – If another ping was sent with the same data and the corresponding pong wasn’t received yet.
- await pong(data=b'')[source]#
Send a Pong.
An unsolicited pong may serve as a unidirectional heartbeat.
Canceling
pong()
is discouraged. Ifpong()
doesn’t return immediately, it means the write buffer is full. If you don’t want to wait, you should close the connection.- Parameters:
data (Data) – Payload of the pong. A string will be encoded to UTF-8.
- Raises:
ConnectionClosed – When the connection is closed.
WebSocket connection objects also provide these attributes:
- logger: Logger | LoggerAdapter#
Logger for this connection.
- property local_address: Any#
Local address of the connection.
For IPv4 connections, this is a
(host, port)
tuple.The format of the address depends on the address family; see
getsockname()
.None
if the TCP connection isn’t established yet.
- property remote_address: Any#
Remote address of the connection.
For IPv4 connections, this is a
(host, port)
tuple.The format of the address depends on the address family; see
getpeername()
.None
if the TCP connection isn’t established yet.
- property open: bool#
True
when the connection is open;False
otherwise.This attribute may be used to detect disconnections. However, this approach is discouraged per the EAFP principle. Instead, you should handle
ConnectionClosed
exceptions.
- property closed: bool#
True
when the connection is closed;False
otherwise.Be aware that both
open
andclosed
areFalse
during the opening and closing sequences.
- latency: float#
Latency of the connection, in seconds.
This value is updated after sending a ping frame and receiving a matching pong frame. Before the first ping,
latency
is0
.By default, websockets enables a keepalive mechanism that sends ping frames automatically at regular intervals. You can also send ping frames and measure latency with
ping()
.
The following attributes are available after the opening handshake, once the WebSocket connection is open:
- subprotocol: Subprotocol | None#
Subprotocol, if one was negotiated.
The following attributes are available after the closing handshake, once the WebSocket connection is closed:
- property close_code: int | None#
WebSocket close code, defined in section 7.1.5 of RFC 6455.
None
if the connection isn’t closed yet.
- property close_reason: str | None#
WebSocket close reason, defined in section 7.1.6 of RFC 6455.
None
if the connection isn’t closed yet.