Comunicação remota do C# serviço no com o Reliable ServicesService remoting in C# with Reliable Services

Para serviços que não estão vinculados a um determinado protocolo de comunicação ou pilha, como uma API Web, Windows Communication Foundation ou outros, a estrutura de Reliable Services fornece um mecanismo de comunicação remota para configurar de forma rápida e fácil as chamadas de procedimento remoto para serviços.For services that aren't tied to a particular communication protocol or stack, such as a web API, Windows Communication Foundation, or others, the Reliable Services framework provides a remoting mechanism to quickly and easily set up remote procedure calls for services. Este artigo discute como configurar chamadas de procedimento remoto para serviços escritos com C#o.This article discusses how to set up remote procedure calls for services written with C#.

Configurar a comunicação remota em um serviçoSet up remoting on a service

Você pode configurar a comunicação remota para um serviço em duas etapas simples:You can set up remoting for a service in two simple steps:

  1. Crie uma interface para o serviço implementar.Create an interface for your service to implement. Essa interface define os métodos que estão disponíveis para uma chamada de procedimento remoto em seu serviço.This interface defines the methods that are available for a remote procedure call on your service. Os métodos devem ser métodos assíncronos que retornam tarefas.The methods must be task-returning asynchronous methods. A interface deve implementar Microsoft.ServiceFabric.Services.Remoting.IService para sinalizar que o serviço tem uma interface de comunicação remota.The interface must implement Microsoft.ServiceFabric.Services.Remoting.IService to signal that the service has a remoting interface.
  2. Use um ouvinte de comunicação remota em seu serviço.Use a remoting listener in your service. Um ouvinte de comunicação remota é uma implementação ICommunicationListener que fornece recursos de comunicação remota.A remoting listener is an ICommunicationListener implementation that provides remoting capabilities. O namespace Microsoft.ServiceFabric.Services.Remoting.Runtime contém o método de extensão CreateServiceRemotingInstanceListeners para serviços com e sem estado que podem ser usados para criar um ouvinte de comunicação remota usando o protocolo de transporte remoto padrão.The Microsoft.ServiceFabric.Services.Remoting.Runtime namespace contains the extension method CreateServiceRemotingInstanceListeners for both stateless and stateful services that can be used to create a remoting listener by using the default remoting transport protocol.

Nota

O namespace Remoting está disponível como um pacote NuGet separado chamado Microsoft.ServiceFabric.Services.Remoting.The Remoting namespace is available as a separate NuGet package called Microsoft.ServiceFabric.Services.Remoting.

Por exemplo, o serviço sem estado a seguir expõe um único método para obter "Olá, Mundo" sobre uma chamada de procedimento remoto.For example, the following stateless service exposes a single method to get "Hello World" over a remote procedure call.

using Microsoft.ServiceFabric.Services.Communication.Runtime;
using Microsoft.ServiceFabric.Services.Remoting;
using Microsoft.ServiceFabric.Services.Remoting.Runtime;
using Microsoft.ServiceFabric.Services.Runtime;

public interface IMyService : IService
{
    Task<string> HelloWorldAsync();
}

class MyService : StatelessService, IMyService
{
    public MyService(StatelessServiceContext context)
        : base (context)
    {
    }

    public Task<string> HelloWorldAsync()
    {
        return Task.FromResult("Hello!");
    }

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
     return this.CreateServiceRemotingInstanceListeners();
    }
}

Nota

Os argumentos e os tipos de retorno na interface de serviço podem ser de tipos simples, complexos ou personalizados, mas eles devem ser capazes de serem serializados pelo DataContractSerializerdo .net.The arguments and the return types in the service interface can be any simple, complex, or custom types, but they must be able to be serialized by the .NET DataContractSerializer.

Chamar métodos de serviço remotoCall remote service methods

Chamar métodos em um serviço usando a pilha de comunicação remota é feito usando um proxy local para o serviço por meio da classe Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxy.Calling methods on a service by using the remoting stack is done by using a local proxy to the service through the Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxy class. O método ServiceProxy cria um proxy local usando a mesma interface implementada pelo serviço.The ServiceProxy method creates a local proxy by using the same interface that the service implements. Com esse proxy, você pode chamar métodos na interface remotamente.With that proxy, you can call methods on the interface remotely.


IMyService helloWorldClient = ServiceProxy.Create<IMyService>(new Uri("fabric:/MyApplication/MyHelloWorldService"));

string message = await helloWorldClient.HelloWorldAsync();

A estrutura de comunicação remota propaga exceções geradas pelo serviço para o cliente.The remoting framework propagates exceptions thrown by the service to the client. Como resultado, quando ServiceProxyis usado, o cliente é responsável por manipular as exceções geradas pelo serviço.As a result, when ServiceProxyis used, the client is responsible for handling the exceptions thrown by the service.

Tempo de vida do proxy de serviçoService proxy lifetime

A criação de proxy de serviço é uma operação leve, para que você possa criar quantos forem necessários.Service proxy creation is a lightweight operation, so you can create as many as you need. As instâncias de proxy de serviço podem ser reutilizadas desde que sejam necessárias.Service proxy instances can be reused for as long as they are needed. Se uma chamada de procedimento remoto lançar uma exceção, você ainda poderá reutilizar a mesma instância de proxy.If a remote procedure call throws an exception, you can still reuse the same proxy instance. Cada proxy de serviço contém um cliente de comunicação usado para enviar mensagens pela conexão.Each service proxy contains a communication client used to send messages over the wire. Ao invocar chamadas remotas, verificações internas são executadas para determinar se o cliente de comunicação é válido.While invoking remote calls, internal checks are performed to determine if the communication client is valid. Com base nos resultados dessas verificações, o cliente de comunicação é recriado, se necessário.Based on the results of those checks, the communication client is re-created if needed. Portanto, se ocorrer uma exceção, você não precisará recriar ServiceProxy.Therefore, if an exception occurs, you do not need to re-create ServiceProxy.

Tempo de vida da fábrica de proxy de serviçoService proxy factory lifetime

ServiceProxyFactory é uma fábrica que cria instâncias de proxy para diferentes interfaces de comunicação remota.ServiceProxyFactory is a factory that creates proxy instances for different remoting interfaces. Se você usar a API ServiceProxyFactory.CreateServiceProxy para criar um proxy, a estrutura criará um proxy de serviço singleton.If you use the API ServiceProxyFactory.CreateServiceProxy to create a proxy, the framework creates a singleton service proxy. É útil criar um manualmente quando você precisa substituir as propriedades IServiceRemotingClientFactory .It is useful to create one manually when you need to override IServiceRemotingClientFactory properties. A criação de fábrica é uma operação cara.Factory creation is an expensive operation. Uma fábrica de proxy de serviço mantém um cache interno do cliente de comunicação.A service proxy factory maintains an internal cache of the communication client. Uma prática recomendada é armazenar em cache a fábrica de proxy de serviço pelo máximo de tempo possível.A best practice is to cache the service proxy factory for as long as possible.

Manipulação de exceção de comunicação remotaRemoting exception handling

Todas as exceções remotas geradas pela API de serviço são enviadas de volta ao cliente como AggregateException.All remote exceptions thrown by the service API are sent back to the client as AggregateException. Exceções remotas devem ser capazes de ser serializadas pelo DataContract.Remote exceptions should be able to be serialized by DataContract. Se não forem, a API de proxy lançará ServiceException com o erro de serialização nele.If they are not, the proxy API throws ServiceException with the serialization error in it.

O proxy de serviço trata todas as exceções de failover para a partição de serviço para a qual ela é criada.The service proxy handles all failover exceptions for the service partition it is created for. Ele resolverá novamente os pontos de extremidade se houver exceções de failover (exceções não transitórias) e tentará novamente a chamada com o ponto de extremidade correto.It re-resolves the endpoints if there are failover exceptions (non-transient exceptions) and retries the call with the correct endpoint. O número de repetições para exceções de failover é indefinido.The number of retries for failover exceptions is indefinite. Se ocorrerem exceções transitórias, o proxy tentará novamente a chamada.If transient exceptions occur, the proxy retries the call.

Os parâmetros de repetição padrão são fornecidos pelo OperationRetrySettings.Default retry parameters are provided by OperationRetrySettings.

Um usuário pode configurar esses valores passando o objeto OperationRetrySettings para o Construtor ServiceProxyFactory.A user can configure these values by passing the OperationRetrySettings object to the ServiceProxyFactory constructor.

Usar a pilha v2 de comunicação remotaUse the remoting V2 stack

A partir da versão 2,8 do pacote de comunicação remota do NuGet, você tem a opção de usar a pilha v2 de comunicação remota.As of version 2.8 of the NuGet remoting package, you have the option to use the remoting V2 stack. A pilha v2 de comunicação remota apresenta melhor desempenho.The remoting V2 stack performs better. Ele também fornece recursos como serialização personalizada e mais APIs conectáveis.It also provides features like custom serialization and more pluggable APIs. O código do modelo continua a usar a pilha remota v1.Template code continues to use the remoting V1 stack. A comunicação remota v2 não é compatível com V1 (a pilha remota anterior).Remoting V2 is not compatible with V1 (the previous remoting stack). Siga as instruções no artigo Atualizar de v1 para v2 para evitar efeitos sobre a disponibilidade do serviço.Follow the instructions in the article Upgrade from V1 to V2 to avoid effects on service availability.

As abordagens a seguir estão disponíveis para habilitar a pilha v2.The following approaches are available to enable the V2 stack.

Usar um atributo de assembly para usar a pilha v2Use an assembly attribute to use the V2 stack

Essas etapas alteram o código do modelo para usar a pilha v2 usando um atributo de assembly.These steps change the template code to use the V2 stack by using an assembly attribute.

  1. Altere o recurso de ponto de extremidade de "ServiceEndpoint" para "ServiceEndpointV2" no manifesto do serviço.Change the endpoint resource from "ServiceEndpoint" to "ServiceEndpointV2" in the service manifest.

    <Resources>
     <Endpoints>
       <Endpoint Name="ServiceEndpointV2" />
     </Endpoints>
    </Resources>
    
  2. Use o método de extensão Microsoft.ServiceFabric.Services.Remoting.Runtime.CreateServiceRemotingInstanceListeners para criar ouvintes de comunicação remota (igual para v1 e v2).Use the Microsoft.ServiceFabric.Services.Remoting.Runtime.CreateServiceRemotingInstanceListeners extension method to create remoting listeners (equal for both V1 and V2).

     protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
     {
         return this.CreateServiceRemotingInstanceListeners();
     }
    
  3. Marque o assembly que contém as interfaces de comunicação remota com um atributo FabricTransportServiceRemotingProvider.Mark the assembly that contains the remoting interfaces with a FabricTransportServiceRemotingProvider attribute.

    [assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2, RemotingClientVersion = RemotingClientVersion.V2)]
    

Nenhuma alteração de código é necessária no projeto cliente.No code changes are required in the client project. Crie o assembly de cliente com o assembly de interface para certificar-se de que o atributo de assembly mostrado anteriormente é usado.Build the client assembly with the interface assembly to make sure that the assembly attribute previously shown is used.

Usar classes v2 explícitas para usar a pilha v2Use explicit V2 classes to use the V2 stack

Como alternativa ao uso de um atributo de assembly, a pilha V2 também pode ser habilitada usando classes v2 explícitas.As an alternative to using an assembly attribute, the V2 stack also can be enabled by using explicit V2 classes.

Essas etapas alteram o código do modelo para usar a pilha v2 usando classes v2 explícitas.These steps change the template code to use the V2 stack by using explicit V2 classes.

  1. Altere o recurso de ponto de extremidade de "ServiceEndpoint" para "ServiceEndpointV2" no manifesto do serviço.Change the endpoint resource from "ServiceEndpoint" to "ServiceEndpointV2" in the service manifest.

    <Resources>
     <Endpoints>
       <Endpoint Name="ServiceEndpointV2" />
     </Endpoints>
    </Resources>
    
  2. Use FabricTransportServiceRemotingListener do namespace Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime.Use FabricTransportServiceRemotingListener from the Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime namespace.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
     {
         return new[]
         {
             new ServiceInstanceListener((c) =>
             {
                 return new FabricTransportServiceRemotingListener(c, this);
    
             })
         };
     }
    
  3. Use FabricTransportServiceRemotingClientFactory do namespace Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Client para criar clientes.Use FabricTransportServiceRemotingClientFactory from the Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Client namespace to create clients.

    var proxyFactory = new ServiceProxyFactory((c) =>
           {
               return new FabricTransportServiceRemotingClientFactory();
           });
    

Atualização do Remoting v1 para o Remoting v2Upgrade from remoting V1 to remoting V2

Para atualizar de v1 para v2, são necessárias atualizações em duas etapas.To upgrade from V1 to V2, two-step upgrades are required. Siga as etapas nesta sequência.Follow the steps in this sequence.

  1. Atualize o serviço v1 para o serviço v2 usando este atributo.Upgrade the V1 service to V2 service by using this attribute. Essa alteração certifica-se de que o serviço escuta no ouvinte v1 e v2.This change makes sure that the service listens on the V1 and V2 listener.

    a.a. Adicione um recurso de ponto de extremidade com o nome "ServiceEndpointV2" no manifesto do serviço.Add an endpoint resource with the name "ServiceEndpointV2" in the service manifest.

    <Resources>
      <Endpoints>
        <Endpoint Name="ServiceEndpointV2" />  
      </Endpoints>
    </Resources>
    

    b.b. Use o método de extensão a seguir para criar um ouvinte de comunicação remota.Use the following extension method to create a remoting listener.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return this.CreateServiceRemotingInstanceListeners();
    }
    

    c.c. Adicione um atributo de assembly em interfaces de comunicação remota para usar o ouvinte v1 e V2 e o cliente v2.Add an assembly attribute on remoting interfaces to use the V1 and V2 listener and the V2 client.

    [assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2|RemotingListenerVersion.V1, RemotingClientVersion = RemotingClientVersion.V2)]
    
    
  2. Atualize o cliente v1 para um cliente v2 usando o atributo cliente v2.Upgrade the V1 client to a V2 client by using the V2 client attribute. Essa etapa garante que o cliente use a pilha v2.This step makes sure the client uses the V2 stack. Nenhuma alteração no projeto/serviço do cliente é necessária.No change in the client project/service is required. A criação de projetos de cliente com o assembly de interface atualizado é suficiente.Building client projects with updated interface assembly is sufficient.

  3. Este passo é opcional.This step is optional. Use o atributo de ouvinte V2 e, em seguida, atualize o serviço v2.Use the V2 listener attribute, and then upgrade the V2 service. Essa etapa garante que o serviço esteja escutando apenas no ouvinte v2.This step makes sure that the service is listening only on the V2 listener.

    [assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2, RemotingClientVersion = RemotingClientVersion.V2)]
    

Usar a pilha do Remoting v2 (compatível com a interface)Use the remoting V2 (interface compatible) stack

A pilha remota v2 (compatível com a interface, conhecida como V2_1) tem todos os recursos da pilha de comunicação remota v2.The remoting V2 (interface compatible, known as V2_1) stack has all the features of the V2 remoting stack. Sua pilha de interface é compatível com a pilha de comunicação remota v1, mas não é compatível com a versão V2 e v1.Its interface stack is compatible with the remoting V1 stack, but it is not backward compatible with V2 and V1. Para atualizar de v1 para V2_1 sem afetar a disponibilidade do serviço, siga as etapas no artigo atualizar de v1 para v2 (compatível com a interface).To upgrade from V1 to V2_1 without affecting service availability, follow the steps in the article Upgrade from V1 to V2 (interface compatible).

Usar um atributo de assembly para usar a pilha do Remoting v2 (compatível com a interface)Use an assembly attribute to use the remoting V2 (interface compatible) stack

Siga estas etapas para mudar para uma pilha V2_1.Follow these steps to change to a V2_1 stack.

  1. Adicione um recurso de ponto de extremidade com o nome "ServiceEndpointV2_1" no manifesto do serviço.Add an endpoint resource with the name "ServiceEndpointV2_1" in the service manifest.

    <Resources>
     <Endpoints>
       <Endpoint Name="ServiceEndpointV2_1" />  
     </Endpoints>
    </Resources>
    
  2. Use o método de extensão de comunicação remota para criar um ouvinte de comunicação remota.Use the remoting extension method to create a remoting listener.

     protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
     {
         return this.CreateServiceRemotingInstanceListeners();
     }
    
  3. Adicione um atributo de assembly em interfaces de comunicação remota.Add an assembly attribute on remoting interfaces.

     [assembly:  FabricTransportServiceRemotingProvider(RemotingListenerVersion=  RemotingListenerVersion.V2_1, RemotingClientVersion= RemotingClientVersion.V2_1)]
    
    

Nenhuma alteração é necessária no projeto cliente.No changes are required in the client project. Crie o assembly de cliente com o assembly de interface para certificar-se de que o atributo de assembly anterior está sendo usado.Build the client assembly with the interface assembly to make sure that the previous assembly attribute is being used.

Usar classes de comunicação remota explícitas para criar uma fábrica de ouvinte/cliente para a versão v2 (compatível com interface)Use explicit remoting classes to create a listener/client factory for the V2 (interface compatible) version

Siga estes passos.Follow these steps:

  1. Adicione um recurso de ponto de extremidade com o nome "ServiceEndpointV2_1" no manifesto do serviço.Add an endpoint resource with the name "ServiceEndpointV2_1" in the service manifest.

    <Resources>
     <Endpoints>
       <Endpoint Name="ServiceEndpointV2_1" />  
     </Endpoints>
    </Resources>
    
  2. Use o ouvinte remoto v2.Use the remoting V2 listener. O nome de recurso do ponto de extremidade de serviço padrão usado é "ServiceEndpointV2_1".The default service endpoint resource name used is "ServiceEndpointV2_1." Ele deve ser definido no manifesto do serviço.It must be defined in the service manifest.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
     {
         return new[]
         {
             new ServiceInstanceListener((c) =>
             {
                 var settings = new FabricTransportRemotingListenerSettings();
                 settings.UseWrappedMessage = true;
                 return new FabricTransportServiceRemotingListener(c, this,settings);
    
             })
         };
     }
    
  3. Use a fábrica de clientev2.Use the V2 client factory.

    var proxyFactory = new ServiceProxyFactory((c) =>
           {
             var settings = new FabricTransportRemotingSettings();
             settings.UseWrappedMessage = true;
             return new FabricTransportServiceRemotingClientFactory(settings);
           });
    

Atualização do Remoting v1 para o Remoting v2 (compatível com a interface)Upgrade from remoting V1 to remoting V2 (interface compatible)

Para atualizar da v1 para a v2 (compatível com a interface, conhecida como V2_1), são necessárias atualizações em duas etapas.To upgrade from V1 to V2 (interface compatible, known as V2_1), two-step upgrades are required. Siga as etapas nesta sequência.Follow the steps in this sequence.

Nota

Ao atualizar do v1 para o v2, verifique se o namespace Remoting está atualizado para usar v2.When upgrading from V1 to V2, ensure the Remoting namespace is updated to use V2. Exemplo: ' Microsoft. FabricTransport. Services. Remoting. v2. Client 'Example: 'Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Client`

  1. Atualize o serviço v1 para o serviço V2_1 usando o atributo a seguir.Upgrade the V1 service to V2_1 service by using the following attribute. Essa alteração garante que o serviço esteja escutando no ouvinte v1 e V2_1.This change makes sure that the service is listening on the V1 and the V2_1 listener.

    a.a. Adicione um recurso de ponto de extremidade com o nome "ServiceEndpointV2_1" no manifesto do serviço.Add an endpoint resource with the name "ServiceEndpointV2_1" in the service manifest.

    <Resources>
      <Endpoints>
        <Endpoint Name="ServiceEndpointV2_1" />  
      </Endpoints>
    </Resources>
    

    b.b. Use o método de extensão a seguir para criar um ouvinte de comunicação remota.Use the following extension method to create a remoting listener.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return this.CreateServiceRemotingInstanceListeners();
    }
    

    c.c. Adicione um atributo de assembly em interfaces de comunicação remota para usar o ouvinte v1, V2_1 e o cliente V2_1.Add an assembly attribute on remoting interfaces to use the V1, V2_1 listener, and V2_1 client.

    [assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2_1 | RemotingListenerVersion.V1, RemotingClientVersion = RemotingClientVersion.V2_1)]
    
    
  2. Atualize o cliente v1 para o cliente V2_1 usando o atributo de cliente V2_1.Upgrade the V1 client to the V2_1 client by using the V2_1 client attribute. Essa etapa garante que o cliente esteja usando a pilha V2_1.This step makes sure the client is using the V2_1 stack. Nenhuma alteração no projeto/serviço do cliente é necessária.No change in the client project/service is required. A criação de projetos de cliente com o assembly de interface atualizado é suficiente.Building client projects with updated interface assembly is sufficient.

  3. Este passo é opcional.This step is optional. Remova a versão v1 do ouvinte do atributo e, em seguida, atualize o serviço v2.Remove the V1 listener version from the attribute, and then upgrade the V2 service. Essa etapa garante que o serviço esteja escutando apenas no ouvinte v2.This step makes sure that the service is listening only on the V2 listener.

    [assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2_1, RemotingClientVersion = RemotingClientVersion.V2_1)]
    

Usar a serialização personalizada com uma mensagem encapsulada de comunicação remotaUse custom serialization with a remoting wrapped message

Para uma mensagem encapsulada de comunicação remota, criamos um único objeto encapsulado com todos os parâmetros como um campo nele.For a remoting wrapped message, we create a single wrapped object with all the parameters as a field in it. Siga estes passos.Follow these steps:

  1. Implemente a interface IServiceRemotingMessageSerializationProvider para fornecer implementação para serialização personalizada.Implement the IServiceRemotingMessageSerializationProvider interface to provide implementation for custom serialization. Esse trecho de código mostra a aparência da implementação.This code snippet shows what the implementation looks like.

    public class ServiceRemotingJsonSerializationProvider : IServiceRemotingMessageSerializationProvider
    {
      public IServiceRemotingMessageBodyFactory CreateMessageBodyFactory()
      {
        return new JsonMessageFactory();
      }
    
      public IServiceRemotingRequestMessageBodySerializer CreateRequestMessageSerializer(Type serviceInterfaceType, IEnumerable<Type> requestWrappedType, IEnumerable<Type> requestBodyTypes = null)
      {
        return new ServiceRemotingRequestJsonMessageBodySerializer();
      }
    
      public IServiceRemotingResponseMessageBodySerializer CreateResponseMessageSerializer(Type serviceInterfaceType, IEnumerable<Type> responseWrappedType, IEnumerable<Type> responseBodyTypes = null)
      {
        return new ServiceRemotingResponseJsonMessageBodySerializer();
      }
    }
    
      class JsonMessageFactory : IServiceRemotingMessageBodyFactory
          {
    
            public IServiceRemotingRequestMessageBody CreateRequest(string interfaceName, string methodName, int numberOfParameters, object wrappedRequestObject)
            {
              return new JsonBody(wrappedRequestObject);
            }
    
            public IServiceRemotingResponseMessageBody CreateResponse(string interfaceName, string methodName, object wrappedRequestObject)
            {
              return new JsonBody(wrappedRequestObject);
            }
          }
    
    class ServiceRemotingRequestJsonMessageBodySerializer : IServiceRemotingRequestMessageBodySerializer
      {
          private JsonSerializer serializer;
    
          public ServiceRemotingRequestJsonMessageBodySerializer()
          {
            serializer = JsonSerializer.Create(new JsonSerializerSettings()
            {
              TypeNameHandling = TypeNameHandling.All
              });
            }
    
            public IOutgoingMessageBody Serialize(IServiceRemotingRequestMessageBody serviceRemotingRequestMessageBody)
           {
             if (serviceRemotingRequestMessageBody == null)
             {
               return null;
             }          
             using (var writeStream = new MemoryStream())
             {
               using (var jsonWriter = new JsonTextWriter(new StreamWriter(writeStream)))
               {
                 serializer.Serialize(jsonWriter, serviceRemotingRequestMessageBody);
                 jsonWriter.Flush();
                 var bytes = writeStream.ToArray();
                 var segment = new ArraySegment<byte>(bytes);
                 var segments = new List<ArraySegment<byte>> { segment };
                 return new OutgoingMessageBody(segments);
               }
             }
            }
    
            public IServiceRemotingRequestMessageBody Deserialize(IIncomingMessageBody messageBody)
           {
             using (var sr = new StreamReader(messageBody.GetReceivedBuffer()))
             {
               using (JsonReader reader = new JsonTextReader(sr))
               {
                 var ob = serializer.Deserialize<JsonBody>(reader);
                 return ob;
               }
             }
           }
          }
    
    class ServiceRemotingResponseJsonMessageBodySerializer : IServiceRemotingResponseMessageBodySerializer
     {
       private JsonSerializer serializer;
    
      public ServiceRemotingResponseJsonMessageBodySerializer()
      {
        serializer = JsonSerializer.Create(new JsonSerializerSettings()
        {
            TypeNameHandling = TypeNameHandling.All
          });
        }
    
        public IOutgoingMessageBody Serialize(IServiceRemotingResponseMessageBody responseMessageBody)
        {
          if (responseMessageBody == null)
          {
            return null;
          }
    
          using (var writeStream = new MemoryStream())
          {
            using (var jsonWriter = new JsonTextWriter(new StreamWriter(writeStream)))
            {
              serializer.Serialize(jsonWriter, responseMessageBody);
              jsonWriter.Flush();
              var bytes = writeStream.ToArray();
              var segment = new ArraySegment<byte>(bytes);
              var segments = new List<ArraySegment<byte>> { segment };
              return new OutgoingMessageBody(segments);
            }
          }
        }
    
        public IServiceRemotingResponseMessageBody Deserialize(IIncomingMessageBody messageBody)
        {
    
           using (var sr = new StreamReader(messageBody.GetReceivedBuffer()))
           {
             using (var reader = new JsonTextReader(sr))
             {
               var obj = serializer.Deserialize<JsonBody>(reader);
               return obj;
             }
           }
         }
     }
    
    class JsonBody : WrappedMessage, IServiceRemotingRequestMessageBody, IServiceRemotingResponseMessageBody
    {
          public JsonBody(object wrapped)
          {
            this.Value = wrapped;
          }
    
          public void SetParameter(int position, string parameName, object parameter)
          {  //Not Needed if you are using WrappedMessage
            throw new NotImplementedException();
          }
    
          public object GetParameter(int position, string parameName, Type paramType)
          {
            //Not Needed if you are using WrappedMessage
            throw new NotImplementedException();
          }
    
          public void Set(object response)
          { //Not Needed if you are using WrappedMessage
            throw new NotImplementedException();
          }
    
          public object Get(Type paramType)
          {  //Not Needed if you are using WrappedMessage
            throw new NotImplementedException();
          }
    }
    
  2. Substitua o provedor de serialização padrão por JsonSerializationProvider para um ouvinte de comunicação remota.Override the default serialization provider with JsonSerializationProvider for a remoting listener.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[]
        {
            new ServiceInstanceListener((c) =>
            {
                return new FabricTransportServiceRemotingListener(c, this,
                    new ServiceRemotingJsonSerializationProvider());
            })
        };
    }
    
  3. Substitua o provedor de serialização padrão por JsonSerializationProvider para uma fábrica de cliente de comunicação remota.Override the default serialization provider with JsonSerializationProvider for a remoting client factory.

    var proxyFactory = new ServiceProxyFactory((c) =>
    {
        return new FabricTransportServiceRemotingClientFactory(
        serializationProvider: new ServiceRemotingJsonSerializationProvider());
      });
    

Passos seguintesNext steps