मैंने एक .NET कोर स्टेटलेस सर्विस फैब्रिक एप्लिकेशन (v 3.0.467) बनाया है। मुझे इस सेवा के लिए KestrelCommunicationListener और ServiceProxy रिमोट कॉल दोनों का उपयोग करने की आवश्यकता है।

जब मैं स्थानीय क्लस्टर में एप्लिकेशन को तैनात कर रहा हूं, तो यह एक अपवाद फेंक रहा है:

जब एकाधिक संचार श्रोताओं का उपयोग किया जाता है तो प्रत्येक श्रोता के लिए अद्वितीय नाम निर्दिष्ट किया जाना चाहिए सर्विस फैब्रिक एक्सप्लोरर एक्सेप्शन

मैंने 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

2
cva 6 मई 2018, 09:58

1 उत्तर

सबसे बढ़िया उत्तर

आपने कई ServiceInstanceListeners को परिभाषित किया है। सर्विस फैब्रिक को अलग करने के लिए आपको 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"); 
2
Community 20 जून 2020, 12:12