in src/Microsoft.Azure.Relay/WebSockets/NetStandard20/WebSocketHandle.Managed.cs [77:170]
public Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
_webSocket.SendAsync(buffer, messageType, endOfMessage, cancellationToken);
public Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken) =>
_webSocket.ReceiveAsync(buffer, cancellationToken);
public Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) =>
_webSocket.CloseAsync(closeStatus, statusDescription, cancellationToken);
public Task CloseOutputAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken) =>
_webSocket.CloseOutputAsync(closeStatus, statusDescription, cancellationToken);
public async Task ConnectAsyncCore(Uri uri, CancellationToken cancellationToken, ClientWebSocket clientWebSocket, ClientWebSocketOptions options)
{
// TODO #14480 : Not currently implemented, or explicitly ignored:
// - ClientWebSocketOptions.UseDefaultCredentials
// - ClientWebSocketOptions.Credentials
// - ClientWebSocketOptions._sendBufferSize
// Establish connection to the server
CancellationTokenRegistration registration = cancellationToken.Register(s => ((WebSocketHandle)s).Abort(), this);
try
{
Socket connectedSocket;
Stream stream;
Uri proxyUri = options.Proxy != null && options.Proxy != WebRequest.DefaultWebProxy ? options.Proxy.GetProxy(uri) : null;
if (proxyUri != null)
{
connectedSocket = await ConnectSocketAsync(proxyUri.Host, proxyUri.Port, cancellationToken).ConfigureAwait(false);
stream = new AsyncEventArgsNetworkStream(connectedSocket);
await ConnectWithProxyAsync(uri, options, stream, cancellationToken).ConfigureAwait(false);
}
else
{
// Connect to the remote server
connectedSocket = await ConnectSocketAsync(uri.Host, uri.Port, cancellationToken).ConfigureAwait(false);
stream = new AsyncEventArgsNetworkStream(connectedSocket);
}
// Upgrade to SSL if needed
if (uri.Scheme == UriScheme.Wss)
{
var sslStream = new SslStream(stream);
await sslStream.AuthenticateAsClientAsync(
uri.Host,
options.ClientCertificates,
SecurityProtocol.AllowedSecurityProtocols,
checkCertificateRevocation: false).ConfigureAwait(false);
stream = sslStream;
}
// Create the security key and expected response, then build all of the request headers
KeyValuePair<string, string> secKeyAndSecWebSocketAccept = CreateSecKeyAndSecWebSocketAccept();
byte[] requestHeader = BuildRequestHeader(uri, options, secKeyAndSecWebSocketAccept.Key);
// Write out the header to the connection
await stream.WriteAsync(requestHeader, 0, requestHeader.Length, cancellationToken).ConfigureAwait(false);
// Parse the response and store our state for the remainder of the connection
string subprotocol = await ParseAndValidateConnectResponseAsync(stream, clientWebSocket, options, secKeyAndSecWebSocketAccept.Value, cancellationToken).ConfigureAwait(false);
_webSocket = ManagedWebSocket.CreateFromConnectedStream(
stream, false, subprotocol, options.KeepAliveInterval, options.ReceiveBufferSize, options.Buffer);
// If a concurrent Abort or Dispose came in before we set _webSocket, make sure to update it appropriately
if (_state == WebSocketState.Aborted)
{
_webSocket.Abort();
}
else if (_state == WebSocketState.Closed)
{
_webSocket.Dispose();
}
}
catch (Exception exc)
{
if (_state < WebSocketState.Closed)
{
_state = WebSocketState.Closed;
}
Abort();
if (exc is WebSocketException)
{
throw;
}
throw new WebSocketException(SR.net_webstatus_ConnectFailure, exc);
}
finally
{
registration.Dispose();
}
}