Вызов службы Service Fabric из консольного приложения с использованием конечной точки HTTPS WCF

У меня есть служба, размещенная в кластере Service Fabric в Azure (не локально), и я пытаюсь вызвать в ней метод с помощью консольного приложения на моей локальной машине. Используя WCF для связи, я настроил конечную точку HTTPS в своем приложении на определенный порт и настроил правила балансировки нагрузки для порта на портале Azure. Кластер имеет 6 узлов, и приложение является единственным, развернутым в кластере.

Следовали за ServiceFabric.WcfCalc на GitHub ( ссылка), который работает в локальном кластере с использованием конечных точек HTTP, но не может вызвать метод службы с использованием конечных точек HTTPS после ее развертывания. Что мне нужно сделать, чтобы это заработало? Попытался следовать приведенному здесь примеру, но не знаю, как настроить это для HTTPS со службой на нескольких узлах для доступа к консольному приложению.

Заранее спасибо.

РЕДАКТИРОВАТЬ Вот мой клиентский код, который я использую для вызова метода обслуживания. Я передаю ткань:/ URI в конструктор здесь.

public class Client : ServicePartitionClient<WcfCommunicationClient<IServiceInterface>>, IServiceInterface
{
    private static ICommunicationClientFactory<WcfCommunicationClient<IServiceInterface>> communicationClientFactory;

    static Client()
    {
        communicationClientFactory = new WcfCommunicationClientFactory<IServiceInterface>(
            clientBinding: new BasicHttpBinding(BasicHttpSecurityMode.Transport));
    }

    public Client(Uri serviceUri)
        : this(serviceUri, ServicePartitionKey.Singleton)
    { }

    public Client(
        Uri serviceUri,
        ServicePartitionKey partitionKey)
        : base(
            communicationClientFactory,
            serviceUri,
            partitionKey)
    { }


    public Task<bool> ServiceMethod(DataClass data)
    {
        try
        {
             //It hangs here
            return this.InvokeWithRetry((c) => c.Channel.ServiceMethod(data));
        }
        catch (Exception)
        {
            throw;
        }
    }
}

При отладке моего консольного приложения на моем локальном компьютере приложение зависает при вызове InvokeWithRetry, который вызывает метод в моей службе в Service Fabric. Приложение не выдает никаких исключений и не возвращает отладчик в Visual Studio.

2 ответа

  • Убедитесь, что вы запускаете каждый экземпляр / реплику службы с уникальным URL.

  • Убедитесь, что вы звоните WebHttpBinding конструктор, использующий WebHttpSecurityMode.Transport,

  • Убедитесь, что вы зарегистрировали URL-адрес, используя тот же номер порта (вероятно, 443), что и в декларации конечной точки вашего манифеста службы.

  • Убедитесь, что конечная точка настроена как HTTPS.

Предупреждение, которое вы видите в Service Fabric, говорит о том, что уже есть еще одна служба, которую можно прослушивать. port 443 на ваших узлах. Это означает, что Service Fabric не может раскрутить ваш сервис (поскольку он выдает внутреннее исключение, когда пытается зарегистрировать URL-адрес в http.sys). Вы можете изменить порт для вашего сервиса на другой, который не будет конфликтовать с существующим сервисом, например:

<Resources>
  <Endpoint Name="CalculatorEndpoint" Protocol="https" Type="Input" Port="44330" />
</Endpoints>

Если вы войдете в Service Fabric Explorer на https://{cluster_name}.{region}.cloudapp.azure.com:19080 вы сможете увидеть, какие другие приложения и службы работают там. Если вы расширите сервисы до самого узла, вы сможете увидеть зарегистрированные конечные точки, включая порты, для существующих сервисов.

Бонус Вы можете запросить кластер, используя FabricClient для всех зарегистрированных конечных точек

var fabricClient = new FabricClient();
var applicationList = fabricClient.QueryManager.GetApplicationListAsync().GetAwaiter().GetResult();
foreach (var application in applicationList)
{
    var serviceList = fabricClient.QueryManager.GetServiceListAsync(application.ApplicationName).GetAwaiter().GetResult();
    foreach (var service in serviceList)
    {
        var partitionListAsync = fabricClient.QueryManager.GetPartitionListAsync(service.ServiceName).GetAwaiter().GetResult();
        foreach (var partition in partitionListAsync)
        {
            var replicas = fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id).GetAwaiter().GetResult();
            foreach (var replica in replicas)
            {
                if (!string.IsNullOrWhiteSpace(replica.ReplicaAddress))
                {
                    var replicaAddress = JObject.Parse(replica.ReplicaAddress);
                    foreach (var endpoint in replicaAddress["Endpoints"])
                    {
                        var endpointAddress = endpoint.First().Value<string>();
                        Console.WriteLine($"{service.ServiceName} {endpointAddress} {endpointAddress}");
                    }
}}}}}

Просто запустите его с надлежащими учетными данными FabricClient (если это защищенный кластер), и вы увидите, что в нем перечислены все конечные точки для всех служб. Это должно помочь вам найти тот, который имеет конечную точку для:443

Другие вопросы по тегам