.. currentmodule:: websockets
Feature support matrices summarize which implementations support which features.
.support-matrix-table { width: 100%; } .support-matrix-table th:first-child { text-align: left; } .support-matrix-table th:not(:first-child) { text-align: center; width: 15%; } .support-matrix-table td:not(:first-child) { text-align: center; }| |aio| | |sync| | |trio| | Sans-I/O | |leg| | |
|---|---|---|---|---|---|
| Perform the opening handshake | ✅ | ✅ | ✅ | ✅ | ✅ |
| Enforce opening timeout | ✅ | ✅ | ✅ | — | ✅ |
| Send a message | ✅ | ✅ | ✅ | ✅ | ✅ |
| Broadcast a message | ✅ | ❌ | ❌ | — | ✅ |
| Receive a message | ✅ | ✅ | ✅ | ✅ | ✅ |
| Iterate over received messages | ✅ | ✅ | ✅ | — | ✅ |
| Send a fragmented message | ✅ | ✅ | ✅ | ✅ | ✅ |
| Receive a fragmented message frame by frame | ✅ | ✅ | ✅ | — | ❌ |
| Receive a fragmented message after reassembly | ✅ | ✅ | ✅ | — | ✅ |
| Force sending a message as Text or Binary | ✅ | ✅ | ✅ | — | ❌ |
| Force receiving a message as :class:`bytes` or :class:`str` | ✅ | ✅ | ✅ | — | ❌ |
| Send a ping | ✅ | ✅ | ✅ | ✅ | ✅ |
| Respond to pings automatically | ✅ | ✅ | ✅ | ✅ | ✅ |
| Send a pong | ✅ | ✅ | ✅ | ✅ | ✅ |
| Keepalive | ✅ | ✅ | ✅ | — | ✅ |
| Heartbeat | ✅ | ✅ | ✅ | — | ✅ |
| Measure latency | ✅ | ✅ | ✅ | — | ✅ |
| Perform the closing handshake | ✅ | ✅ | ✅ | ✅ | ✅ |
| Enforce closing timeout | ✅ | ✅ | ✅ | — | ✅ |
| Report close codes and reasons from both sides | ✅ | ✅ | ✅ | ✅ | ❌ |
| Compress messages (RFC 7692) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Tune memory usage for compression | ✅ | ✅ | ✅ | ✅ | ✅ |
| Negotiate extensions | ✅ | ✅ | ✅ | ✅ | ✅ |
| Implement custom extensions | ✅ | ✅ | ✅ | ✅ | ✅ |
| Negotiate a subprotocol | ✅ | ✅ | ✅ | ✅ | ✅ |
| Enforce security limits | ✅ | ✅ | ✅ | ✅ | ✅ |
| Log events | ✅ | ✅ | ✅ | ✅ | ✅ |
| |aio| | |sync| | |trio| | Sans-I/O | |leg| | |
|---|---|---|---|---|---|
| Listen on a TCP socket | ✅ | ✅ | ✅ | — | ✅ |
| Listen on a Unix socket | ✅ | ✅ | ❌ | — | ✅ |
| Listen using a preexisting socket | ✅ | ✅ | ✅ | — | ✅ |
| Encrypt connection with TLS | ✅ | ✅ | ✅ | — | ✅ |
| Close server on context exit | ✅ | ✅ | ✅ | — | ✅ |
| Close connection on handler exit | ✅ | ✅ | ✅ | — | ✅ |
| Shut down server gracefully | ✅ | ✅ | ✅ | — | ✅ |
Check Origin header |
✅ | ✅ | ✅ | ✅ | ✅ |
| Customize subprotocol selection | ✅ | ✅ | ✅ | ✅ | ✅ |
Configure Server header |
✅ | ✅ | ✅ | ✅ | ✅ |
| Alter opening handshake request | ✅ | ✅ | ✅ | ✅ | ❌ |
| Alter opening handshake response | ✅ | ✅ | ✅ | ✅ | ❌ |
| Force an HTTP response | ✅ | ✅ | ✅ | ✅ | ✅ |
| Perform HTTP Basic Authentication | ✅ | ✅ | ✅ | ❌ | ✅ |
| Route connections to handlers | ✅ | ✅ | ❌ | — | ❌ |
| |aio| | |sync| | |trio| | Sans-I/O | |leg| | |
|---|---|---|---|---|---|
| Connect to a TCP socket | ✅ | ✅ | ✅ | — | ✅ |
| Connect to a Unix socket | ✅ | ✅ | ❌ | — | ✅ |
| Connect using a preexisting socket | ✅ | ✅ | ✅ | — | ✅ |
| Encrypt connection with TLS | ✅ | ✅ | ✅ | — | ✅ |
| Close connection on context exit | ✅ | ✅ | ✅ | — | ✅ |
| Reconnect automatically | ✅ | ❌ | ✅ | — | ✅ |
Configure Origin header |
✅ | ✅ | ✅ | ✅ | ✅ |
Configure User-Agent header |
✅ | ✅ | ✅ | ✅ | ✅ |
| Modify opening handshake request | ✅ | ✅ | ✅ | ✅ | ✅ |
| Modify opening handshake response | ✅ | ✅ | ✅ | ✅ | ❌ |
| Connect to non-ASCII IRIs | ✅ | ✅ | ✅ | ✅ | ✅ |
| Follow HTTP redirects | ✅ | ❌ | ✅ | — | ✅ |
| Perform HTTP Basic Authentication | ✅ | ✅ | ✅ | ✅ | ✅ |
| Connect via HTTP proxy | ✅ | ✅ | ✅ | — | ❌ |
| Connect via SOCKS5 proxy | ✅ | ✅ | ✅ | — | ❌ |
There is no way to control compression of outgoing frames on a per-frame basis (#538). If compression is enabled, all frames are compressed.
The server doesn't check the Host header and doesn't respond with HTTP 400 Bad Request if it is missing or invalid (#1246).
The client doesn't support HTTP Digest Authentication (#784).
The client API doesn't attempt to guarantee that there is no more than one connection to a given IP address in a CONNECTING state. This behavior is mandated by RFC 6455, section 4.1. However, :func:`~asyncio.client.connect()` isn't the right layer for enforcing this constraint. It's the caller's responsibility.
It is possible to send or receive a text message containing invalid UTF-8 with
send(not_utf8_bytes, text=True) and not_utf8_bytes = recv(decode=False)
respectively. As a side effect of disabling UTF-8 encoding and decoding, these
options also disable UTF-8 validation.