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

时间:2018-05-06 06:58:31

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

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

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

  

当使用多个通信侦听器时,必须为每个侦听器指定唯一名称   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

1 个答案:

答案 0 :(得分:1)

您已定义了多个ServiceInstanceListeners。为了使Service Fabric能够区分它们,您需要使用name构造函数的可选ServiceInstanceListener参数来命名它们。见the docs

  

命名

     

通讯监听器的名称。如果无状态服务只有一个通信侦听器,则此参数是可选的。如果未给出,则将Name设置为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");