Skip to content

Commit af37422

Browse files
author
Katya Sokolova
committed
Add WebSockets conceptual doc
1 parent efcb6c7 commit af37422

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# WebSockets support in .NET
2+
3+
The WebSocket Protocol enables two-way communication between a client to a remote host that has opted-in to communications from that code. The <xref:System.Net.WebSockets.Client.ClientWebSocket?displayProperty=fullName> exposes the ability to establish WebSocket connection via an opening handshake: it is created and sent by `ConnectAsync` method.
4+
5+
## HTTP/2 vs HTTP/1.1 WebSockets
6+
7+
WebSockets over HTTP/1.1 uses a single TCP connection, therefore it is managed by connection-wide headers (see [RFC 6455](https://www.rfc-editor.org/rfc/rfc6455)). Here is an example of how to establish WebSocket over HTTP/1.1:
8+
9+
```c#
10+
ClientWebSocket ws = new();
11+
ws.ConnectAsync(uri, cancellationToken);
12+
```
13+
14+
A different approach must be taken with HTTP/2 due to its multiplexing nature: here, WebSockets are established per stream (see [RFC 8441](https://www.rfc-editor.org/rfc/rfc8441)). With HTTP/2 it is possible to use one connection for multiple web socket streams together with ordinary HTTP streams and extends HTTP/2's more efficient use of the network to WebSockets. There is a special overload of `ConnectAsync` which accepts `HttpMessageInvoker` to allow reusing existing pooled connections:
15+
16+
```c#
17+
var handler = new SocketsHttpHandler();
18+
ClientWebSocket ws = new();
19+
ws.ConnectAsync(uri, new HttpMessageInvoker(handler), cancellationToken);
20+
```
21+
22+
## How to set up HTTP version and policy
23+
24+
By default, `ClientWebSocket` uses HTTP/1.1 to send an opening handshake and allows downgrade. It can be changed before calling `ConnectAsync`:
25+
26+
```c#
27+
ClientWebSocket ws = new();
28+
29+
ws.Options.HttpVersion = HttpVersion.Version20;
30+
ws.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
31+
32+
ws.ConnectAsync(uri, new HttpMessageInvoker(handler), cancellationToken);
33+
```
34+
35+
## Incompatible options
36+
37+
`ClientWebSocket` has properties <xref:System.Net.WebSockets.Client.ClientWebSocketOptions?displayProperty=fullName> that the user can set up before the connection is established. However, when `HttpMessageInvoker` is provided, it also has these properties. To avoid ambiguity, in that case, properties should be set on `HttpMessageInvoker`, and `ClientWebSocketOptions` should have default values. Otherwise, if `ClientWebSocketOptions` are changed, overload of `ConnectAsync` will throw an <xref:System.ArgumentException>.
38+
39+
## Compression
40+
41+
WebSocket supports per-message deflate as defined in [RFC 7692](https://tools.ietf.org/html/rfc7692#section-7). It is controlled by <xref:System.Net.WebSockets.Client.ClientWebSocketOptions.DangerousDeflateOptions?displayProperty=fullName>. When present, the options are sent to the server during the handshake phase. If the server supports per-message-deflate and the options are accepted, the <see cref="WebSocket"/> instance will be created with compression enabled by default for all messages.
42+
43+
> [!IMPORTANT]
44+
> Before using it, please be aware that enabling compression makes the application subject to CRIME/BREACH type of attacks. It is strongly advised to turn off compression when sending data containing secrets by specifying `DisableCompression` flag for such messages.

0 commit comments

Comments
 (0)