-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
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 through ServicePoint.SetTcpKeepAlive.
Proposed API
// Using a class, so we can set default values for properties
// The verbose name is here to avoid potential future conflicts
// with a TcpKeepAlive type we may define in System.Net.Sockets
public class WinHttpTcpKeepAlive
{
// Must be greater than TimeSpan.Zero
// Hard coded default value: 2 hours (based on Windows default)
public TimeSpan KeepAliveTime { get; set; }
// Must be greater than TimeSpan.Zero
// Hard coded default value: 1 sec (based on Windows default)
public TimeSpan KeepAliveInterval { get; set; }
}
public class WinHttpHandler
{
#if NET5
[SupportedOSPlatform("windows10.0.2004")]
#endif
// If the option is not supported by the OS, WinHttpException will be thrown during FIRST REQUEST (just like with other options).
// We may consider throwing `PlatformNotSupprtedException` below version 2004, although that would be unprecedental in WinHttpHandler
public WinHttpTcpKeepAlive? TcpKeepAlive { get; set; }
}Usage Examples
static HttpClient CreateHttpClient()
{
var winHttpHandler = new WinHttpHandler()
{
TcpKeepAlive = new WinHttpTcpKeepAlive()
{
KeepAliveTime = TimeSpan.FromMinutes(2),
KeepAliveInterval = TimeSpan.FromSeconds(2)
}
}
return new HttpClient(winHttpHandler);
}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_keepalivewe 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.