Pilha de comunicação baseada em WCF para serviços confiáveis

A estrutura de Serviços Confiáveis permite que os autores de serviços escolham a pilha de comunicação que desejam usar para seu serviço. Eles podem conectar a pilha de comunicação de sua escolha por meio do ICommunicationListener retornado dos métodos CreateServiceReplicaListeners ou CreateServiceInstanceListeners . A estrutura fornece uma implementação da pilha de comunicação com base no Windows Communication Foundation (WCF) para autores de serviço que desejam usar a comunicação baseada em WCF.

Ouvinte de comunicação WCF

A implementação específica do WCF de ICommunicationListener é fornecida pela classe Microsoft.ServiceFabric.Services.Communication.Wcf.Runtime.WcfCommunicationListener .

Para não dizer que temos um contrato de prestação de serviços do tipo ICalculator

[ServiceContract]
public interface ICalculator
{
    [OperationContract]
    Task<int> Add(int value1, int value2);
}

Podemos criar um ouvinte de comunicação WCF no serviço da seguinte maneira.


protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
    return new[] { new ServiceReplicaListener((context) =>
        new WcfCommunicationListener<ICalculator>(
            wcfServiceObject:this,
            serviceContext:context,
            //
            // The name of the endpoint configured in the ServiceManifest under the Endpoints section
            // that identifies the endpoint that the WCF ServiceHost should listen on.
            //
            endpointResourceName: "WcfServiceEndpoint",

            //
            // Populate the binding information that you want the service to use.
            //
            listenerBinding: WcfUtility.CreateTcpListenerBinding()
        )
    )};
}

Escrevendo clientes para a pilha de comunicação WCF

Para escrever clientes para se comunicar com serviços usando WCF, a estrutura fornece WcfClientCommunicationFactory, que é a implementação específica do WCF de ClientCommunicationFactoryBase.


public WcfCommunicationClientFactory(
    Binding clientBinding = null,
    IEnumerable<IExceptionHandler> exceptionHandlers = null,
    IServicePartitionResolver servicePartitionResolver = null,
    string traceId = null,
    object callback = null);

O canal de comunicação WCF pode ser acessado a partir do WcfCommunicationClient criado pelo WcfCommunicationClientFactory.


public class WcfCommunicationClient : ServicePartitionClient<WcfCommunicationClient<ICalculator>>
   {
       public WcfCommunicationClient(ICommunicationClientFactory<WcfCommunicationClient<ICalculator>> communicationClientFactory, Uri serviceUri, ServicePartitionKey partitionKey = null, TargetReplicaSelector targetReplicaSelector = TargetReplicaSelector.Default, string listenerName = null, OperationRetrySettings retrySettings = null)
           : base(communicationClientFactory, serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings)
       {
       }
   }

O código do cliente pode usar o WcfCommunicationClientFactory junto com o WcfCommunicationClient que implementa ServicePartitionClient para determinar o ponto de extremidade do serviço e se comunicar com o serviço.

// Create binding
Binding binding = WcfUtility.CreateTcpClientBinding();
// Create a partition resolver
IServicePartitionResolver partitionResolver = ServicePartitionResolver.GetDefault();
// create a  WcfCommunicationClientFactory object.
var wcfClientFactory = new WcfCommunicationClientFactory<ICalculator>
    (clientBinding: binding, servicePartitionResolver: partitionResolver);

//
// Create a client for communicating with the ICalculator service that has been created with the
// Singleton partition scheme.
//
var calculatorServiceCommunicationClient =  new WcfCommunicationClient(
                wcfClientFactory,
                ServiceUri,
                ServicePartitionKey.Singleton);

//
// Call the service to perform the operation.
//
var result = calculatorServiceCommunicationClient.InvokeWithRetryAsync(
                client => client.Channel.Add(2, 3)).Result;

Nota

O ServicePartitionResolver padrão pressupõe que o cliente está sendo executado no mesmo cluster que o serviço. Se esse não for o caso, crie um objeto ServicePartitionResolver e passe os pontos de extremidade de conexão de cluster.

Próximos passos