2

I have created a .NET Core stateless Service Fabric application (v 3.0.467). I need to use both KestrelCommunicationListener and a ServiceProxy remote call for this service.

When I am deploying the application to the local cluster, it's throwing an exception:

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

I have configured as below in the servicemanifest.xml file

<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>

and code sample:

  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();
                    }))
         };
        }

Is there any mistake in this configuration?

Update:

Below code is the service sample method calling from the client:

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

Client code:

 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;
        }

Sample code is in following GitHub link: serviceappcode

4

1 回答 1

2

您已经定义了多个 ServiceInstanceListener。为了让 Service Fabric 区分它们,您需要name使用ServiceInstanceListener. 请参阅文档

姓名

通信侦听器的名称。如果无状态服务只有一个通信侦听器,则此参数是可选的。如果未给出,则将 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"); 
于 2018-05-06T07:35:10.980 回答