Description
Justification
Long-running but idle connections (which happen in gRPC and long poll scenarios) can result in firewalls/etc. dropping connections out from under us, without any reset notification. This causes long timeouts on a client that is only reading data.
These APIs will have HttpClient periodically send ping frames over HTTP/2, which would prevent firewalls from seeing the connection as idle and detect otherwise broken connections sooner than we can right now.
API Proposal
public class SocketsHttpHandler
{
// if we haven't received data on a connection in X time, send a PING frame.
public TimeSpan KeepAlivePingDelay { get; set; }
// if server does not respond to the PING in X time, kill the connection on our side.
public TimeSpan KeepAlivePingTimeout { get; set; }
// ****new since last review****
public HttpKeepAlivePingPolicy KeepAlivePingPolicy { get; set; }
}
// Consider using a bool instead. Proposing enum for better extensibility in future.
public enum HttpKeepAlivePingPolicy
{
// Only send pings if there are active requests.
WithActiveRequests,
// Send pings even for idle connections.
// Common gRPC servers have behavior that will kill connections that use this. ¯\_(ツ)_/¯
Always
}
Original issue below
I've been evaluating the new gRPC-dotnet and particularly its streaming feature in a long lived connected scenario.
I needed the HTTP/2 PING feature to detect the zombie connections (basically to know: "Am I still having an up and running connection to the client?") on both server and client side.
It seems that this feature won't be implement-able on the client side as long as there's no support of an API in the HttpClient, as the client part of gRPC-dotnet relies on HttpClient.
It seems that HttpClient already responds to ping but can not send any on demand. Am I right?
So I would like to request a new method in HttpClient class to support sending Http/2 pings or even better a kind of keep alive ping timeout to do it automatically in case there's no traffic...
BTW: I have also created an issue for the same feature for kestrel (I don't know what kestrel is using underneath).