h2-ws-client
Minimal client-side WebSocket over HTTP/2, built on top of hyper and tokio-tungstenite.
The goal of this crate is to provide a very small abstraction for WebSocket over HTTP/2 using RFC 8441 “Extended CONNECT”, without trying to be a full-featured WebSocket client.
⚠️ Warning
This is intentionally a minimal implementation.
It is not battle-tested, and using it in production is entirely at your own risk. You may need to add your own error handling, reconnection logic, TLS, timeouts, etc.
Compatibility
This crate is designed to work with servers that implement
RFC 8441: Bootstrapping WebSockets with HTTP/2.
- axum (via
WebSocketUpgrade) already supports WebSockets over HTTP/2 using the extendedCONNECT+:protocol = "websocket"flow. - reqwest is an HTTP client and does not provide any WebSocket
abstraction (neither over HTTP/1.1 nor HTTP/2). If you need WebSockets,
you typically combine
hyper+tokio-tungstenite(or a crate like this one).
How RFC 8441 WebSockets Work
RFC 8441 defines how to bootstrap WebSockets over HTTP/2 using an extended CONNECT request:
-
The client sends an HTTP/2 request:
:method = CONNECT:protocol = "websocket":path = "/your-endpoint"sec-websocket-version = 13(and optionallysec-websocket-protocol)
-
If the server accepts, it returns a successful
2xxresponse.
From this point on, that single HTTP/2 stream becomes a bidirectional byte stream. -
Over that byte stream, both sides speak normal WebSocket frames as defined in RFC 6455 (text, binary, ping/pong, close, masking, etc.).
diagram description of (3)
So conceptually:
-
WebSocket over HTTP/1.1
- Uses
GET ... HTTP/1.1+Upgrade: websocket - After
101 Switching Protocols, the whole TCP connection is “taken over” by WebSocket.
- Uses
-
WebSocket over HTTP/2 (RFC 8441)
- Uses
CONNECT+:protocol = "websocket" - Only one HTTP/2 stream (not the entire connection) is used as the underlying WebSocket channel.
- Other HTTP/2 streams can still be used for normal HTTP traffic.
- Uses
This crate only cares about the client side of that HTTP/2 WebSocket flow.
Running tests and examples
1. Run tests
This will run both unit tests and integration tests (for example, against an axum echo server).
2-1. Run the example server
# In one terminal: run your server (axum / hyper / etc.)
# For example:
2-2. Run the example client
Assuming you have a compatible server listening on 127.0.0.1:3000 and serving
a WebSocket endpoint at /echo (for example, an axum WebSocketUpgrade handler):
# In another terminal: run the example client
You should then be able to type into the client and see the server’s responses.
Example: Interactive HTTP/2 WebSocket client
use ;
use ;
use ;
use Message;
async