Background and motivation
One of the original motivations behind #861 / #87932 was to utilize Happy Eyeballs in SocketsHttpHandler, see #26177 (comment), however since then the SocketsHttpHandler code has been updated to use the ValueTask overload. Unless we are willing to duplicate code into SocketsHttpHandler, the SAEA overload is insufficient for utilizing Happy Eyeballs in SocketsHttpHandler. Moreover ValueTask-based overloads would be more useful for the general public.
API Proposal
namespace System.Net.Sockets;
public class Socket
{
// Existing:
public ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken);
public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType, SocketAsyncEventArgs e)
// Approved in #861 / #87932
public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType, SocketAsyncEventArgs e, ConnectAlgorithm connectAlgorithm);
// Proposed:
public ValueTask ConnectAsync(DnsEndPoint remoteEP, ConnectAlgorithm connectAlgorithm, CancellationToken cancellationToken = default);
// Also consider (needs more implementation work)
public ValueTask ConnectAsync(IPAddress[] addresses, int port, ConnectAlgorithm connectAlgorithm, CancellationToken cancellationToken)
}
API Usage
Using DnsEndpoint overload in SocketsHttpHandler (simplified)
public async ValueTask<Stream> ConnectToTcpHostAsync(string host, int port, CancellationToken cancellationToken)
{
try
{
Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true };
await socket.ConnectAsync(endPoint, ConnectAlgorithm.Parallel, cancellationToken).ConfigureAwait(false);
return new NetworkStream(socket, ownsSocket: true);
}
catch
{
socket.Dispose();
throw;
}
}
Using IPAddress[] overload in ConnectCallback
using SocketsHttpHandler handler = new SocketsHttpHandler();
handler.ConnectCallback = async (ctx, ct) =>
{
DnsEndPoint dnsEndPoint = ctx.DnsEndPoint;
IPAddress[] addresses = await Dns.GetHostAddressesAsync(dnsEndPoint.Host, dnsEndPoint.AddressFamily, ct);
LogResolvedAdresses(addresses);
var s = new Socket(SocketType.Stream, ProtocolType.Tcp) { NoDelay = true };
try
{
await s.ConnectAsync(addresses, dnsEndPoint.Port, ConnectAlgorithm.Parallel, ct);
return new NetworkStream(s, ownsSocket: true);
}
catch
{
s.Dispose();
throw;
}
};
Alternative Designs
No response
Risks
I see no high risks from the API itself, however adaption (#26177) should be done with care.
Background and motivation
One of the original motivations behind #861 / #87932 was to utilize Happy Eyeballs in
SocketsHttpHandler, see #26177 (comment), however since then theSocketsHttpHandlercode has been updated to use theValueTaskoverload. Unless we are willing to duplicate code intoSocketsHttpHandler, the SAEA overload is insufficient for utilizing Happy Eyeballs inSocketsHttpHandler. MoreoverValueTask-based overloads would be more useful for the general public.API Proposal
API Usage
Using
DnsEndpointoverload inSocketsHttpHandler(simplified)Using
IPAddress[]overload inConnectCallbackAlternative Designs
No response
Risks
I see no high risks from the API itself, however adaption (#26177) should be done with care.