azure - 当使用多个通信监听器时,必须为每个监听器指定唯一名称

标签 azure azure-service-fabric service-fabric-stateless

我创建了一个 .NET Core 无状态 Service Fabric 应用程序 (v 3.0.467)。我需要为此服务使用 KestrelCommunicationListener 和 ServiceProxy 远程调用。

当我将应用程序部署到本地集群时,它抛出异常:

Unique Name must be specified for each listener when multiple communication listeners are used Service Fabric Explorer exception

我在 servicemanifest.xml 文件中进行了如下配置

<Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to 
           listen. Please note that if your service is partitioned, this port is shared with 
           replicas of different partitions that are placed in your code. -->
      <Endpoint Name="ServiceEndpointV2" />
      <Endpoint Protocol="http" Name="httpServiceEndpoint" Type="Input" Port="9098" />
    </Endpoints>
  </Resources>

和代码示例:

  protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        {
            return new[]
            {
                 new ServiceInstanceListener((context) =>
                {

                    // return new FabricTransportServiceRemotingListener(context, this);

                      return new FabricTransportServiceRemotingListener(context, this,new Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime.FabricTransportRemotingListenerSettings(){EndpointResourceName = "ServiceEndpointV2" });

                }),
                new ServiceInstanceListener(serviceContext =>
                    new KestrelCommunicationListener(serviceContext, "httpServiceEndpoint", (url, listener) =>
                    {
                        ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                        return new WebHostBuilder()
                                    .UseKestrel()
                                    .ConfigureServices(
                                        services => services
                                            .AddSingleton<StatelessServiceContext>(serviceContext))
                                    .UseContentRoot(Directory.GetCurrentDirectory())
                                    .UseStartup<Startup>()
                                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                                    .UseUrls(url)
                                    .Build();
                    }))
         };
        }

这个配置有什么错误吗?

更新:

下面的代码是客户端调用的服务示例方法:

 public Task<string> OnRouteMessageaAsync(string tenant)
   {
            return Task.FromResult(tenant);
   }

客户端代码:

 private async Task<string> RemoteServiceCall()
        {
            try
            {
                var client = ServiceProxy.Create<ICommunication>(new Uri("fabric:/AuthenticationServiceApp/AuthenticationServiceApi"), listenerName: "RemotingListener");
                var response = client.OnRouteMessageaAsync("tenant");
                return response.Result;
            }
            catch (Exception ex)
            {

            }
            return null;
        }

示例代码位于以下 GitHub 链接中: serviceappcode

最佳答案

您定义了多个ServiceInstanceListener。为了让 Service Fabric 区分它们,您需要使用 ServiceInstanceListener 构造函数的可选 name 参数来命名它们。请参阅the docs :

Name

Name of the communication listener. This parameter is optional if the Stateless Service has only one communication listener. If it is not given, the Name is set to DefaultName.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[]
        {
            new ServiceInstanceListener((context) =>
            {

                // return new FabricTransportServiceRemotingListener(context, this);

                return new FabricTransportServiceRemotingListener(context, this,new Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime.FabricTransportRemotingListenerSettings(){EndpointResourceName = "ServiceEndpointV2" });

            }, name: "RemotingListener"),
            new ServiceInstanceListener(serviceContext =>
                new KestrelCommunicationListener(serviceContext, "httpServiceEndpoint", (url, listener) =>
                {
                    ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                    return new WebHostBuilder()
                        .UseKestrel()
                        .ConfigureServices(
                            services => services
                                .AddSingleton<StatelessServiceContext>(serviceContext))
                        .UseContentRoot(Directory.GetCurrentDirectory())
                        .UseStartup<Startup>()
                        .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                        .UseUrls(url)
                        .Build();
                }), name: "KestrelCommunicationListener")
        };
    }

现在,当您使用远程处理调用服务时,也必须使用此名称:

var client = ServiceProxy.Create<ICommunication>(
    new Uri("fabric:/AuthenticationServiceApp/AuthenticationServiceApi"), 
    listenerName: "RemotingListener"); 
var result = client.OnRouteMessageaAsync("topic"); 

关于azure - 当使用多个通信监听器时,必须为每个监听器指定唯一名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50197057/

相关文章:

Azure AD 身份验证重定向循环

c# - IReliableQueue 入队序列化错误

c# - Service Fabric 无法加载程序集 c#

azure - 为开发生命周期配置 Azure ServiceFabric - 如何参数化主机名?

c# - Microsoft.ServiceFabric.Data.Impl.pdb 未加载

azure - 如何使用 Azure PowerShell 获取 Azure KeyVault 的访问策略

c# - Microsoft.Graph.Models.ODataErrors.ODataError 与 .PatchAsync(用户)上的 Graph API

asp.net-mvc-3 - 每次更改一行 CSS 时,是否都需要重新部署到开发盒上的 IIS Express?

c# - 我们如何对服务结构(无状态服务)进行集成测试?

c# - 微服务之间的 Service Fabric wcf 通信