File: Internal\DefaultTransportFactory.cs
Web Access
Project: src\src\SignalR\clients\csharp\Http.Connections.Client\src\Microsoft.AspNetCore.Http.Connections.Client.csproj (Microsoft.AspNetCore.Http.Connections.Client)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
 
namespace Microsoft.AspNetCore.Http.Connections.Client.Internal;
 
internal sealed partial class DefaultTransportFactory : ITransportFactory
{
    private readonly HttpClient? _httpClient;
    private readonly HttpConnectionOptions _httpConnectionOptions;
    private readonly Func<Task<string?>> _accessTokenProvider;
    private readonly HttpTransportType _requestedTransportType;
    private readonly ILoggerFactory _loggerFactory;
    private static volatile bool _websocketsSupported = true;
 
    public DefaultTransportFactory(HttpTransportType requestedTransportType, ILoggerFactory loggerFactory, HttpClient? httpClient, HttpConnectionOptions httpConnectionOptions, Func<Task<string?>> accessTokenProvider)
    {
        if (httpClient == null && requestedTransportType != HttpTransportType.WebSockets)
        {
            throw new ArgumentException($"{nameof(httpClient)} cannot be null when {nameof(requestedTransportType)} is not {nameof(HttpTransportType.WebSockets)}.", nameof(httpClient));
        }
 
        _requestedTransportType = requestedTransportType;
        _loggerFactory = loggerFactory;
        _httpClient = httpClient;
        _httpConnectionOptions = httpConnectionOptions;
        _accessTokenProvider = accessTokenProvider;
    }
 
    public ITransport CreateTransport(HttpTransportType availableServerTransports, bool useStatefulReconnect)
    {
        if (_websocketsSupported && (availableServerTransports & HttpTransportType.WebSockets & _requestedTransportType) == HttpTransportType.WebSockets)
        {
            try
            {
                return new WebSocketsTransport(_httpConnectionOptions, _loggerFactory, _accessTokenProvider, _httpClient, useStatefulReconnect);
            }
            catch (PlatformNotSupportedException ex)
            {
                Log.TransportNotSupported(_loggerFactory.CreateLogger<DefaultTransportFactory>(), HttpTransportType.WebSockets, ex);
                _websocketsSupported = false;
            }
        }
 
        if ((availableServerTransports & HttpTransportType.ServerSentEvents & _requestedTransportType) == HttpTransportType.ServerSentEvents)
        {
            // We don't need to give the transport the accessTokenProvider because the HttpClient has a message handler that does the work for us.
            return new ServerSentEventsTransport(_httpClient!, _httpConnectionOptions, _loggerFactory);
        }
 
        if ((availableServerTransports & HttpTransportType.LongPolling & _requestedTransportType) == HttpTransportType.LongPolling)
        {
            // We don't need to give the transport the accessTokenProvider because the HttpClient has a message handler that does the work for us.
            return new LongPollingTransport(_httpClient!, _httpConnectionOptions, _loggerFactory);
        }
 
        throw new InvalidOperationException("No requested transports available on the server.");
    }
 
    private static partial class Log
    {
        [LoggerMessage(1, LogLevel.Debug, "Transport '{TransportType}' is not supported.", EventName = "TransportNotSupported")]
        public static partial void TransportNotSupported(ILogger logger, HttpTransportType transportType, Exception ex);
    }
}