Features - websockets 12.0 documentation
Description: Feature support matrices summarize which implementations support which features. Both sides:,,,,, asyncio, threading, Sans-I/O,,, Perform the opening handshake, ✅, ✅, ✅,, Send a message, ✅, ✅, ✅,, ...

Hide navigation sidebar
Hide table of contents sidebar
Back to top
Toggle table of contents sidebar

# Features

Feature support matrices summarize which implementations support which features.

## Both sides

| `asyncio` | `threading` | Sans-I/O
--- | --- | --- | ---
Perform the opening handshake | ✅ | ✅ | ✅
Send a message | ✅ | ✅ | ✅
Receive a message | ✅ | ✅ | ✅
Iterate over received messages | ✅ | ✅ | ❌
Send a fragmented message | ✅ | ✅ | ✅
Receive a fragmented message after reassembly | ✅ | ✅ | ❌
Receive a fragmented message frame by frame (#479) | ❌ | ✅ | ✅
Send a ping | ✅ | ✅ | ✅
Respond to pings automatically | ✅ | ✅ | ✅
Send a pong | ✅ | ✅ | ✅
Perform the closing handshake | ✅ | ✅ | ✅
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 | ✅ | ✅ | ✅
Enforce opening timeout | ✅ | ✅ | —
Enforce closing timeout | ✅ | ✅ | —
Keepalive | ✅ | ❌ | —
Heartbeat | ✅ | ❌ | —

## Server

| `asyncio` | `threading` | Sans-I/O
--- | --- | --- | ---
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 | ❌ | ✅ | ✅
Perform HTTP Basic Authentication | ✅ | ❌ | ❌
Perform HTTP Digest Authentication | ❌ | ❌ | ❌
Force HTTP response | ✅ | ✅ | ✅

## Client

| `asyncio` | `threading` | Sans-I/O
--- | --- | --- | ---
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 | ✅ | ✅ | ✅
Alter opening handshake request | ✅ | ✅ | ✅
Connect to non-ASCII IRIs | ✅ | ✅ | ✅
Perform HTTP Basic Authentication | ✅ | ✅ | ✅
Perform HTTP Digest Authentication (#784) | ❌ | ❌ | ❌
Follow HTTP redirects | ✅ | ❌ | —
Connect via a HTTP proxy (#364) | ❌ | ❌ | —
Connect via a SOCKS5 proxy (#475) | ❌ | ❌ | —

## Known limitations

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 respond with a HTTP 400 Bad Request if it is missing or invalid (#1246).

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. However, `connect()` isn’t the right layer for enforcing this constraint. It’s the caller’s responsibility.