【问题标题】:Issue with SignalR primary/secondarySignalR 主要/次要问题
【发布时间】:2020-05-30 04:51:11
【问题描述】:

我有一个使用 SignalR 的 asp dotnet core 3.1 应用程序。根据this documentation,可以添加主次连接。我在我的一项服务中运行此功能,但另一项服务不断出现故障,我不知道为什么。

错误信息:

Connection string missing required properties endpoint and accesskey. (Parameter 'connectionString')

堆栈:

at Microsoft.Azure.SignalR.ConnectionStringParser.Parse(String connectionString)
   at Microsoft.Azure.SignalR.ServiceEndpoint..ctor(String connectionString, EndpointType type, String name)
   at Microsoft.Azure.SignalR.ServiceEndpointManagerBase.<GetEndpoints>d__16.MoveNext()
   at System.Linq.Enumerable.DistinctIterator`1.MoveNext()
   at System.Linq.Lookup`2.Create(IEnumerable`1 source, Func`2 keySelector, IEqualityComparer`1 comparer)
   at System.Linq.GroupedEnumerable`2.GetEnumerator()
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at Microsoft.Azure.SignalR.ServiceEndpointManagerBase.GetValuableEndpoints(IEnumerable`1 endpoints)
   at Microsoft.Azure.SignalR.ServiceEndpointManagerBase..ctor(IEnumerable`1 endpoints, ILogger logger)
   at Microsoft.Azure.SignalR.ServiceEndpointManagerBase..ctor(IServiceEndpointOptions options, ILogger logger)
   at Microsoft.Azure.SignalR.ServiceEndpointManager..ctor(IOptionsMonitor`1 optionsMonitor, ILoggerFactory loggerFactory)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Azure.SignalR.ServiceHubDispatcher.Start(Endpoint endpoint, Type hubType, ConnectionDelegate app)
   at Microsoft.Azure.SignalR.AzureSignalRHostedService.Start()
   at Microsoft.Azure.SignalR.AzureSignalRStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.ApplicationInsights.AspNetCore.ApplicationInsightsStartupFilter.<>c__DisplayClass2_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.<StartAsync>d__31.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__9.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at SigR.Program.Main(String[] args) in G:\Git_Merc\ms-chat\WebApi\Program.cs:line 13

我有这个环境变量:

Azure:SignalR:ConnectionString:Primary

有价值

Endpoint=https://&lt;redacted&gt;;AccessKey=&lt;redacted&gt;Version=1.0;

如果我从密钥中删除:Primary,它可以工作,但它也应该可以工作。我也试过插入一个,比如

Azure:SignalR:ConnectionString:Test:Primary

而且,就像我说的,我有另一个服务使用该密钥。 TBH,我什至不确定 DI 为什么会在应用启动时发现这个问题?

编辑:

添加请求的代码。

var sigrBuilder = services.AddSignalR().AddNewtonsoftJsonProtocol(options =>
            {
                options.PayloadSerializerSettings.Converters = new List<JsonConverter> 
                { 
                    new TransferOptionConverter() //converters for data from mercury
                };
            });
sigrBuilder.AddAzureSignalR();

【问题讨论】:

  • 请在AddAzureSignalR(...)上添加您正在使用的代码。

标签: asp.net-core signalr


【解决方案1】:

原来我在我的 appsettings 文件中复制了一个带有 BS 值的配置,它获取的是那个值,而不是我使用“:Primary”后缀的那个值。当我执行“Azure:SignalR:ConnectionString”时它会起作用,因为它完全匹配并且被覆盖了。一旦我把它吹走,一切都会奏效。

【讨论】:

    【解决方案2】:

    正如您在 this example 中看到的,您应该在添加 Azure SignalR 时指定主要和次要实例,例如:

    var sigrBuilder = services.AddSignalR().AddNewtonsoftJsonProtocol(options =>
    {
        options.PayloadSerializerSettings.Converters = new List<JsonConverter> 
        { 
            new TransferOptionConverter() //converters for data from mercury
        };
    });
    
    sigrBuilder.AddAzureSignalR(options => options.Endpoints = new ServiceEndpoint[]
    {
        new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
        new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
    });
    

    【讨论】:

    • 是的,这就是“代码方式”。它说你应该能够通过配置来做到这一点,这对我来说更可取。 If you have multiple endpoints, you can set them in multiple config entries, each in the following format: Azure:SignalR:ConnectionString:&lt;name&gt;:&lt;role&gt;
    • 当然你不会在这里原始连接字符串和区域,只需从这里读取配置。
    • 对不起,我不明白你想说什么
    • 你在这个方法上注入配置。
    • 是的,我知道可以通过代码完成。我是说我不想那样做,我想通过配置来做到这一点,就像文档说我应该能够做到的那样。
    猜你喜欢
    • 2019-07-15
    • 2011-04-09
    • 2010-12-25
    • 2019-03-28
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2012-06-24
    相关资源
    最近更新 更多