Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocket Keep-Alive #44611

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

WebSocket Keep-Alive #44611

wants to merge 2 commits into from

Conversation

CarnaViire
Copy link
Member

@CarnaViire CarnaViire commented Jan 29, 2025

Moving all the details from the blogpost to the dedicated conceptual doc.

cc @dotnet/ncl

Acrolinx section score 85

image


Internal previews

📄 File 🔗 Preview link
docs/fundamentals/networking/websockets.md WebSockets support in .NET

Comment on lines +109 to +116
1. Keep-Alive is **OFF**, if
- `KeepAliveInterval` is `TimeSpan.Zero` or `Timeout.InfiniteTimeSpan`
2. **Unsolicited PONG**, if
- `KeepAliveInterval` is a positive finite `TimeSpan`, -AND-
- `KeepAliveTimeout` is `TimeSpan.Zero` or `Timeout.InfiniteTimeSpan`
3. **PING/PONG**, if
- `KeepAliveInterval` is a positive finite `TimeSpan`, -AND-
- `KeepAliveTimeout` is a positive finite `TimeSpan`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to use <xref> here instead of code blocks.


If you use `ClientWebSocket`, the default <xref:System.Net.WebSockets.ClientWebSocketOptions.KeepAliveInterval?displayProperty=nameWithType> value is <xref:System.Net.WebSockets.WebSocket.DefaultKeepAliveInterval?displayProperty=nameWithType> (typically 30 seconds). That means, `ClientWebSocket` has the Keep-Alive ON by default, with Unsolicited PONG as the default strategy.

If you want to switch to the PING/PONG strategy, overriding <xref:System.Net.WebSockets.ClientWebSocketOptions.KeepAliveTimeout?displayProperty=nameWithType> is enough:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good suggest that this is an implication of the behavior described before.

Suggested change
If you want to switch to the PING/PONG strategy, overriding <xref:System.Net.WebSockets.ClientWebSocketOptions.KeepAliveTimeout?displayProperty=nameWithType> is enough:
As a result, overriding <xref:System.Net.WebSockets.ClientWebSocketOptions.KeepAliveTimeout?displayProperty=nameWithType> is enough to switch to the PING/PONG strategy if you keep the default value for <xref:System.Net.WebSockets.WebSocket.DefaultKeepAliveInterval?displayProperty=nameWithType>:

### Keep Reading To Process PONGs

> [!NOTE]
> Currently, `WebSocket` ONLY processes incoming frames while there's a `ReceiveAsync` pending.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> Currently, `WebSocket` ONLY processes incoming frames while there's a `ReceiveAsync` pending.
> Currently, `WebSocket` ONLY processes incoming frames while there's a <xref:System.Net.WebSockets.WebSocket.ReceiveAsync%2A> task pending.

var result = await _webSocket.ReceiveAsync(buffer, cts.Token);
```

If the timeout elapses, an outstanding `ReceiveAsync` throws an `OperationCanceledException`:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If the timeout elapses, an outstanding `ReceiveAsync` throws an `OperationCanceledException`:
If the timeout elapses, an outstanding <xref:System.Net.WebSockets.WebSocket.ReceiveAsync%2A> throws an <xref:System.OperationCanceledException>:

> Currently, `WebSocket` ONLY processes incoming frames while there's a `ReceiveAsync` pending.

> [!IMPORTANT]
> If you want to use Keep-Alive Timeout, it's _crucial_ that PONG responses are _promptly processed_. Even if the remote endpoint is alive and properly sends the PONG response, but the `WebSocket` isn't processing the incoming frames, the Keep-Alive mechanism can issue a "false-positive" Abort. This problem can happen if the PONG frame is never picked up from the transport stream before the timeout elapsed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> If you want to use Keep-Alive Timeout, it's _crucial_ that PONG responses are _promptly processed_. Even if the remote endpoint is alive and properly sends the PONG response, but the `WebSocket` isn't processing the incoming frames, the Keep-Alive mechanism can issue a "false-positive" Abort. This problem can happen if the PONG frame is never picked up from the transport stream before the timeout elapsed.
> If you want to use Keep-Alive Timeout, it's _crucial_ that PONG responses are _promptly processed_. Even when the remote endpoint is alive and properly sends the PONG response, if the `WebSocket` isn't processing the incoming frames, the Keep-Alive mechanism can issue a "false-positive" Abort. This problem can happen if the PONG frame is never picked up from the transport stream before the timeout elapsed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants