// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using Microsoft.AspNetCore.SignalR.Internal.Protocol; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.SignalR.Internal { public class DefaultHubProtocolResolver : IHubProtocolResolver { private readonly IOptions _options; private readonly ILogger _logger; private readonly Dictionary _availableProtocols; public DefaultHubProtocolResolver(IOptions options, IEnumerable availableProtocols, ILogger logger) { _options = options ?? throw new ArgumentNullException(nameof(options)); _logger = logger ?? NullLogger.Instance; _availableProtocols = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var protocol in availableProtocols) { if (_availableProtocols.ContainsKey(protocol.Name)) { throw new InvalidOperationException($"Multiple Hub Protocols with the name '{protocol.Name}' were registered."); } Log.RegisteredSignalRProtocol(_logger, protocol.Name, protocol.GetType()); _availableProtocols.Add(protocol.Name, protocol); } } public IHubProtocol GetProtocol(string protocolName, HubConnectionContext connection) { protocolName = protocolName ?? throw new ArgumentNullException(nameof(protocolName)); if (_availableProtocols.TryGetValue(protocolName, out var protocol)) { Log.FoundImplementationForProtocol(_logger, protocolName); return protocol; } throw new NotSupportedException($"The protocol '{protocolName ?? "(null)"}' is not supported."); } private static class Log { // Category: DefaultHubProtocolResolver private static readonly Action _registeredSignalRProtocol = LoggerMessage.Define(LogLevel.Debug, new EventId(1, "RegisteredSignalRProtocol"), "Registered SignalR Protocol: {ProtocolName}, implemented by {ImplementationType}."); private static readonly Action _foundImplementationForProtocol = LoggerMessage.Define(LogLevel.Debug, new EventId(2, "FoundImplementationForProtocol"), "Found protocol implementation for requested protocol: {ProtocolName}."); public static void RegisteredSignalRProtocol(ILogger logger, string protocolName, Type implementationType) { _registeredSignalRProtocol(logger, protocolName, implementationType, null); } public static void FoundImplementationForProtocol(ILogger logger, string protocolName) { _foundImplementationForProtocol(logger, protocolName, null); } } } }