-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
API Proposal: WinHttpHandler.TcpKeepAlive #44025
Comments
Tagging subscribers to this area: @dotnet/ncl |
API Review:
public partial class WinHttpHandler
{
#if NET5
[SupportedOSPlatform("windows10.0.2004")]
#endif
public bool TcpKeepAliveEnabled { get; set; }
#if NET5
[SupportedOSPlatform("windows10.0.2004")]
#endif
public TimeSpan TcpKeepAliveTime { get; set; }
#if NET5
[SupportedOSPlatform("windows10.0.2004")]
#endif
public TimeSpan TcpKeepAliveInterval { get; set; }
} |
// Must be greater than TimeSpan.Zero
// Hard coded default value: 1 sec (based on Windows default)
public TimeSpan KeepAliveInterval { get; set; }
https://tools.ietf.org/html/rfc1122#page-101 A default Given servers like Kestrel and HTTP.sys have a default 2 minute HTTP keep-alive timeout, I wonder why someone would want to enable TCP keep-alive for an HTTP connection. Do we need to expose a similar option in Kestrel? |
I think the referenced text talks about what became "keep alive time" (timeout before starting to exchange keepalive packets) not "keep alive interval" in the implementation.
The reason is probably that HTTP keepalive only works with HTTP2. |
I'm not referring to HTTP/2 pings. I'm referring the the behavior of most HTTP servers which will close HTTP connections if no requests are made within a specified interval. This interval is 2 minutes by default for Kestrel and HTTP.sys. Regardless of TCP keep-alives, servers will close the connection anyway in far less than two hours. If the concern is about what happens if the connection is idle mid-request, servers should close connections that are not uploading request data at a sufficient rate regardless of TCP keep-alives. If the request is upgraded for WebSockets which can be idle, the client can use WebSocket keep-alives. |
Edit: Actually, are you sure about this? I'm still reading this as the minimum default time period without receiving packets before a keep-alive packet can be sent. I did see that 1 second is indeed the documented Windows default though. |
According to my (probably incomplete) understanding: what customers want here is to both overwrite the quoted behavior and also make sure the TCP connections remain open via keepalive.
I think the original intent of the spec doesn't really matter (especially in the context of this proposal) if winsock implemented it differently. The proposed API is platform-specific. |
Implements the final version of the API proposal in #44025 except the [SupportedOSPlatform("windows10.0.2004")] bits
Background and Motivation
Starting from version 20H1 (May 2020 Update) WinHTTP exposes an option (
WINHTTP_OPTION_TCP_KEEPALIVE
) to control TCP keepalive parameters in a way similar to the corresponding IOCTL option in Winsock:https://docs.microsoft.com/en-us/windows/win32/winsock/sio-keepalive-vals#remarks
We have a customer request to expose this option in a managed API over
WinHttpHandler
(goal: meet scalability needs). This would also close a feature gap for users migrating from Framework & HttpWebRequest, where it was possible to control this parameter throughServicePoint.SetTcpKeepAlive
.Proposed API
Usage Examples
Alternative Designs
Instead of exposing a property, expose a method with 3 arguments, like
ServicePoint.SetTcpKeepAlive
.We may consider exposing two separate properties to match the design of the HTTP/2 timeout properties on
SocketsHttpHandler
(see configurable HTTP/2 PING timeouts in HttpClient #31198 (comment)), but with Winsocktcp_keepalive
we are expected to set both values with the single call, so this would require us to add unnecessary arbitrary logic to the managed implementation on a place where users expect a thin wrapper over a native API.Risks
Couldn't identify any.
The text was updated successfully, but these errors were encountered: