in src/Microsoft.Azure.SignalR.Common/ServiceConnections/Internal/WebSocketsTransport.cs [108:155]
public async Task StartAsync(Uri url, CancellationToken cancellationToken = default)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(url);
#else
if (url == null)
{
throw new ArgumentNullException(nameof(url));
}
#endif
var resolvedUrl = ResolveWebSocketsUrl(url);
string accessToken = null;
// We don't need to capture to a local because we never change this delegate.
if (_accessTokenProvider != null)
{
accessToken = await _accessTokenProvider.ProvideAsync();
if (!string.IsNullOrEmpty(accessToken))
{
_webSocket.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}");
}
}
Log.StartTransport(_logger, _webSocketMessageType, resolvedUrl);
try
{
await _webSocket.ConnectAsync(resolvedUrl, cancellationToken);
}
catch (Exception e)
{
_webSocket.Dispose();
throw e.WrapAsAzureSignalRException(accessToken);
}
Log.StartedTransport(_logger);
// Create the pipe pair (Application's writer is connected to Transport's reader, and vice versa)
var options = DefaultOptions;
var pair = DuplexPipe.CreateConnectionPair(options, options);
_transport = pair.Transport;
_application = pair.Application;
// TODO: Handle TCP connection errors
// https://github.com/SignalR/SignalR/blob/1fba14fa3437e24c204dfaf8a18db3fce8acad3c/src/Microsoft.AspNet.SignalR.Core/Owin/WebSockets/WebSocketHandler.cs#L248-L251
Running = ProcessSocketAsync(_webSocket);
}