-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Open
Open
Copy link
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-System.Net.Sockets
Milestone
Description
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.
wfurt, liveans and albi005
Metadata
Metadata
Assignees
Labels
api-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementationarea-System.Net.Sockets