.NET - Invocação de objetos Remotos (Remoting)


O .NET Remoting suporta a comunicação de objetos distribuídos pela utilização da representação binária ou SOAP do fluxo de dados.

Sendo mais direto : O .NET Remoting proporciona que seus aplicativos tenham comunicação com sistemas remotos utilizando protocolos de comunicação.

Uma das vantagens é que podemos aproveitar os recursos de um projeto desktop (Windows Forms) em um projeto web usando o .NET Remoting, efetuando troca de informações entre os processos através de métodos e funções. Dessa forma temos que os objetos distribuídos representam serviços que uma camada de componentes oferece para uma camada de apresentação do sistema. Lembre-se que para que a troca de informações seja possível os objetos devem ser serializáveis.

Os 3 componentes principais do .NET Framework Remoting são:

1. Remotable Object
2. Remote Listener Application - (escuta requisições para o Remote Object)
3. Remote Client Application - (efetua requisições para o Remote Object)

O Remote Object é implementando em uma classe que deriva de System.MarshalByRefObject .

Portanto o Remotable Object é qualquer objeto fora do domínio da aplicação. Qualquer objeto pode ser transformado em um objeto remoto a partir da classe MarshalByRefObject. (Um objeto remoto é derivado da classe MarshalByRefObject)

A classe MarshalByRefObject permite acesso a objetos através de limites de domínio do aplicativo em aplicativos que suporte o Remoting.

Um domínio de aplicativo é uma partição em um processo do sistema operacional onde um ou mais aplicativos residem. Objetos no mesmo domínio do aplicativo se comunicam diretamente.
Objetos em domínios diferentes aplicativos se comunicam por transporte de cópias dos objetos através de limites de domínio de aplicativo, ou usando um proxy para trocar mensagens.

MarshalByRefObject é a classe base para objetos que se comunicam através de limites de domínio de aplicativo, trocar mensagens usando um proxy. Objetos que não herdam de MarshalByRefObject são implicitamente empacotados por valor. Quando um aplicativo remoto referencia um pacote por valor de objeto, uma cópia do objeto é passada através de limites de domínio de aplicativo.

Objetos que não herdem de MarshalByRefObject são chamados de Non-Remotable Objects.

A seguir temos um fluxo básico da arquitetura .NET Remoting:

Quando um cliente chama um método remoto , ele não chama o método diretamente , ele recebe um proxy para o objeto remoto e o utiliza para invocar o método em um Remote Object.

Desde que o proxy recebe a chamada do método do cliente ele codifica a mensagem usando um formato apropriado (Binary Formatter ou SOAP Formatter).

Formatters são usados para codificar e decodificar mensagens antes que elas sejam transportadas pelo Canal.

Existem dois tipos de formatadores suportados:

  • Binary Formatter - (System.RunTime.Serialization.Formatters.Binary) - os dados possuem um tamanho menor;
  • SOAP Formatter - (System.RunTime.Serialization.Formatters.Soap) - dados no formato texto baseado em arquivos XML que podem ser lidos;

A configuração dos formatadores e dos canais é feito através de arquivos de configuração como arquivos XML.

A seguir ele efetua a chamada para o servidor usando um canal selecionado (TcpChannel ,HttpChannel)

Canais são usados para transporta mensagens entre objetos Remotos, sendo assim objetos responsáveis pelo tratamento dos protocolos de rede e formatos de serialização.

Um canal pode ser implementado pela chamada do método ChannelServices.RegisterChannel ou pela utilização do arquivo de configuração mas deve ser registrado antes dos objetos.

Quando um canal é registrado ele automaticamente inicia a escuta para as requisições do cliente em uma porta especificada. Pelo menos um canal deve ser registrado antes que um Remote Object possa ser chamado.

Existem dois tpos de canais :

  • canal HTTP - transporta mensagens para e a partir de objetos remotos usando o protocolo SOAP;
  • canal TCP - usa o formato binário para serializar todas as mensagens para um fluxo binário e transporta o fluxo para uma URL de destino usando o protocolo TCP;

O canal do lado do servidor recebe a requisição do proxy e encaminha para o Servidor no sistema remoto que localiza e invoca os métodos do objeto Remoto.

Quando a execução do método remoto é completada qualquer resultado da chamada é retornado de volta ao cliente.

Antes de uma instância do objeto de um tipo Remotable poder ser acessado ele precisa ser criada e inicializada pelo processo chamado Activation que pode ser classificada em dois modelos: Client-Activated Objects e Server-activated Objects.

A diferença entre client-activated e server-activated é que o primeiro não é realmente criado quando faz a sua instanciação , ao invés disso, ele é criado somente quando necessário.

Por padrão .NET Framework vem com dois formatadores :Binary Formatter or SOAP Formatter e dois canais : TcpChannel ,HttpChannel

Trabalhando com .NET Remoting

1- Criando o Remotable Type

No código abaixo temos um exemplo da criação de um objeto remoto no VB .NET que envia a hora atual para a aplicação cliente usando o Framwork Remoting.

Note que a classe RemoteTime é derivada de MarshalByRefObject e, que no interior da classe ele possui o método getTime() o qual retorna a hora atual de um Remote Object.

Imports System
Public Class RemoteTime
   Inherits MarshalByRefObject

   Private currentTime As String = ""
   
   Public Function getTime() As String
          currentTime = DateTime.Now.ToShortTimeString()
          Return "Hora do servidor remoto : " & currentTime
   End Function 

End Class 

Crie uma aplicação do tipo Class Library no VB .NET e salve com o nome de RemoteTime.vb; em seguida compile o arquivo em um library usando a linha de comando do NET Framework com o seguinte sintaxe:

vbc /t:library RemoteTime.vb

Após isso você irá obter o arquivo RemoteTime.dll .

2- Criando o Remote Listener Application

Agora temos que criar um objeto Listener para permitir que os objetos do domínio da outra aplicação possam criar instâncias do nosso objeto RemoteTime remotamente.

Quando da criação do objeto Listener temos que escolher e registrar o canal para o tratamento do protocolo de rede e do formato de serialização e registrar o Tipo no .NET Remoting de forma que ele possa usar o canal para escutar as requisições para o Tipo.

No exemplo a seguir vamos criar uma aplicação listener chamada TimeListener que irá atuar como um objeto Listener para o Tipo Remoto RemoteTime.

A classe Listener TimeListener precisa estar habilitada a encontrar o arquivo TimeListener.exe.config para carregar a configuração para a classe RemotableType.

Vamos criar uma aplicação do tipo console no VB 2008 Express com o nome TimeListener;

A seguir copie o código abaixo no arquivo TimeListener.vb;

Imports System
Imports System.Runtime.Remoting

Public Class TimeListener
     Public Shared Sub Main()
             RemotingConfiguration.Configure("TimeListener.exe.config")
             Console.WriteLine("Escutando requisições do cliente. Para sair pressione ENTER...")
             Console.ReadLine()
      End Sub
End Class

A seguir temos que criar um arquivo de configuração adicional para fornecer a informação da comunicação para o objeto listener.

O arquivo de configuração é um arquivo padrão XML onde podemos especificar o modo de ativação (Activation Mode) , o tipo Remoto (Remote Type) , Canal , porta para comunicação , etc.

Vemos abaixo o arquivo XML  TimeListener.exe.config:

<configuration>
   <system.runtime.remoting>
     <application>
       <service>
       <wellknown mode="Singleton" type="RemoteTime, RemoteTime" objectUri="RemoteTime.rem" /> 
      </service>
       <channels>
        <channel ref="http" port="9090" /> 
       </channels>
   </application>
    </system.runtime.remoting>
</configuration>

Vamos compilar o arquivo TimeListener.vb usando a ferramenta de linha de comando da plataforma .NET. O comando é o seguinte:

vbc /r:RemoteTime.dll TimeListener.vb

Após compilar você deve obter o arquivo TimeListener.exe.

Criando o aplicação CLiente

3-  Criando o Remote Client Application

A aplicação cliente que faz a chamada ao método do objeto Remoto é muito fácil de criar no VB .NET.

Crie uma nova aplicação do tipo Console no VB .NET com o nome Client e copie o código abaixo no arquivo Client.vb;

Imports System
Imports System.Runtime.Remoting

Public Class Client
   Public Shared Sub Main()
         RemotingConfiguration.Configure("Client.exe.config")
        Dim remoteTimeObject As New RemoteTime()
        Console.WriteLine(remoteTimeObject.getTime())
End Sub
End Class

A aplicação cliente cria uma instância do Tipo remoto RemoteTime e chama o método getTime() ; além disso ela usa o arquivo de configuração cliente.exe.config para obter a informação da comunicação para o Remoting Framework.

Temos então que criar um arquivo de configuração adicional para fornecer a informação da comunicação para o objeto Client.

<configuration>
    <system.runtime.remoting>
      <application>
       <client>
              <wellknown type="RemoteTime, RemoteTime" url="http://localhost:9090/RemoteTime.rem" />
       </client>
     </application>
  </system.runtime.remoting>
</configuration>

Compile o arquivo Client.vb usando a ferramenta da linha de comando do NET Framework SDK. O comando é o seguinte:

vbc /r:RemoteTime.dll Client.vb

iremos obter o arquivo Client.exe.

Compilando e rodando a aplicação

Já temos os arquivos necessários para colocar para funcionar o nosso exemplo de aplicação usando o .NET Remoting. Então vamos lá...

Crie uma nova pasta chamara SRC e ponha os três arquivos que criamos nesta pasta:

1. RemoteTime.vb
2. TimeListener.vb
3. Client.vb

Inclua os dois arquivos de configuração na mesma pasta:

1. TimeListener.exe.config
2. Client.exe.config

Lembre-se que os arquivos já foram compilados usando a ferramenta de linha de comando do .NET Framework SDK. Os comandos usados foram:

vbc /t:library RemoteTime.vb
vbc /r:RemoteTime.dll TimeListener.vb
vbc /r:RemoteTime.dll Client.vb

Nota: Você deve fornecer o caminho físico para cada arquivo na compilação. Ex: se os arquivos estiverem na pasta c:\SRC , você deverá informar:

vbc /r:c:\SRC\RemoteTime.dll c:\SRC\TimeListener.vb

Após compilar os arquivos fontes deveremos obter os 3 arquivos na pasta SRC:  RemoteTime.dll , TimeListener.exe e Client.exe

Rodando a aplicação

Agora crie duas novas pastas com o nome Server e Client respectivamente:

- Copie os arquivos : RemoteTime.dll , TimeListener.exe and TimeListener.exe.config para a pasta Server;

- Copie os arquivos:  RemoteTime.dll , Client.exe and Client.exe.config para pasta Client;

Abra um prompt de comando na pasta Server e digite : TimeListener

Você deverá obter uma janela exibindo a mensagem : Escutando requisições do cliente. Para sair pressione ENTER...

Abra um prompt de comando na pasta Client e digite Client;

Você deverá obter a hora atual do objeto remoto.

Nota: Se você obter uma exceção relativa a segurança do IIS você deverá configurar o IIS.

Pronto ! você acabou de criar o seu primeiro programa usando .NET Remoting com sucesso.

Vai parar por ai ???? Que nada , explore mais e vá em frente...

Referências:


José Carlos Macoratti