You are on page 1of 8

Web Services: Componentes provendo Serviços na Web com SOAP e ASP.NET

Vou tentar com este artigo dar uma outra visão do uso dos WebServices, com uma descrição do desenvolvimento de um simples WebServices na plataforma, sem nos aprofundarmos no VisualStudio.NET e sim nas características dos WebServices. A intenção é que este artigo possa ser lido, sem a necessidade obrigatória da leitura do anterior. Inicialmente vamos observar outra vertente do uso dos WebServices, constatando a existência de uma tendência aonde venhamos a utilizar vários aplicativos que acessem serviços na internet (WebServices) ao invés de browser utilizaremos programas como, por exemplo, o já saudoso Napster, que permite buscas em discos de milhares de usuários, que compartilham musicas através de um serviço. Para que possamos desenvolver este tipo programas, é necessária uma forma rápida e fácil de escrever o código que se comunica com outros programas sobre o Internet. A idéia não é nova; temos um grande número de tecnologias existentes que permitem este tipo de uma comunicação: RPC, DCOM, e os serviços da fila de mensagens (MSMQ). Cada uma destas técnicas é quase completa, porém todas têm uma falha fatal: trabalham somente com sistemas similares. O MSMQ fala somente com outro MSMQ, um cliente de DCOM somente a um servidor DCOM, e assim em diante. Precisamos encontrar uma forma de que um programa possa trocar mensagens com outro, de forma independente, não somente do sistema operacional, mas também das instruções internas dos programas. (Ou ficaremos para sempre com as perguntas: Qual é a linguagem? De qual fabricante é? Qual sua versão?).

Solução de arquitetura

A única maneira para tratar o número enorme de entidades heterogêneas na Internet é usar o denominador comum mais baixo. Ou seja, quando os bytes são transferidos de um site para outro, o processo necessita utilizar algum padrão que todos na Internet, suportem. O protocolo mais comum de transferência na Web é o HTTP. O padrão entre plataformas para pegarmos uma informação, codificá-la, transferi-la sobre HTTP é o XML. A Microsoft uniu estas idéias e desenvolveu o conceito de WebService - uma maneira "seamless" de objetos em um servidor aceitarem pedidos dos clientes usando o HTTP e o XML. Para criar um WebService, simplesmente escrevemos uma aplicação servidora Microsoft.NET como se ele fosse acessado por clientes locais, informando que desejamos que ele seja disponível como um cliente Web, e deixe que, o ASP.NET faça o resto. Isto automaticamente se encaixa acima de uma infra-estrutura pré-fabricada que aceite pedidos entrantes através do HTTP e os trace os mesmos para chamar o objeto.

Figura 1. Com um WebService, os objetos podem ser acessados por qualquer pessoa na Web, desde que fale HTTP e XML.

No lado do cliente, o .NET fornece as classes do proxy que têm o fácil acesso,

No lado do cliente, o .NET fornece as classes do proxy que têm o fácil acesso, funções baseadas em WebServices fornecidos por todos os servidores que aceitam pedidos do HTTP, como mostrado na figura 2. Uma ferramenta de desenvolvimento lê a descrição do WebService e gera uma classe proxy que possui funções na linguagem utilizada para desenvolver o cliente. Quando o cliente chama uma destas funções, a classe do proxy gera um pedido do HTTP e emite-o ao servidor. Quando a resposta volta do servidor, a classe do proxy analisa gramaticalmente os resultados e retorna-os da função. Isto permite que sua função baseada em cliente interaja “seamlessly” com todo o WebServer que se comunica via HTTP e XML.

No lado do cliente, o .NET fornece as classes do proxy que têm o fácil acesso,

Figura 2: Escrevendo um Web Service

Escrever o WebService muito simples; pode-se usar o notepad. O programa começa com a

saudação padrão <%@

%>

do ASP.NET. Nela, a diretriz orientadora do WebService diz a

... ASP.NET que o código na página deve ser exposto como um WebService. O atributo da língua diz ao ASP que línguagem compilar o código da página. O ASP.NET usará Visual Basic.NET para compilar o código. O resto da página contém o código que executa a classe. Primeiramente a diretriz orientadora das importações, uma característica nova do Visual Basic.NET, diz ao compilador para importar os "namespaces". O termo “namespace” é conceitualmente idêntico a uma referência em no projeto em Visual Básic 6.0. O ASP.NET compilará o código deste exemplo “just-in-time” quando o pedido chegar de um cliente. Os nomes que seguem as importações dizem ao compilador que grupos de funcionalidade devem ser incluídos na referência. Veremos uma keyword brandnew (Herança) na extremidade da linha: Herança WebService. Isto representa uma das principais características do Visual Basic.NET - suporte

a um conceito de orientação-objeto chamado herança.

Quando se diz que a nova classe TimeService herda da classe WebService, está se informando ao compilador para fazer o exame de todo a classe providenciada pelo WebService (conhecido como a classe baixa) e incluí-lo em sua nova classe de TimeService (sabida como a classe derivada). Podendo haver reutilização do código da classe que herdada, podemos adicionar, alterar, e cancelar as funcionalidades dessa classe. A classe do WebService é fornecida pelo novo .NET runtime library, assim como muitos objetos usados Visual Basic 6.0 são providenciados pelo sistema operacional. WebService possui todo a arquitetura pré-fabricada requerida para segurar os pedidos entrantes do HTTP para distribuí-los aos métodos apropriados ao objeto. Para definir os métodos e as funções da classe. Vamos pensar outra vez, de forma similar ao Visual Basic 6.0, mas com uma novidade: temos que adicionar um atributo novo, < WebMethod() >, a cada método que se queira que seja exposto aos clientes da Web. Isto diz ao ASP.NET que o método deve ser exposto aos clientes como um serviço Web. Apenas sua classe pode conter métodos públicos e privados, assim podendo conter métodos que estão expostos aos clientes da Web ou não.

Quando se diz que a nova classe TimeService herda da classe WebService, está se informando ao

Figura 3: TimeService.asmx em um Browser

Agora vamos acessar o serviço do Web de um cliente. Podemos acessar o código gerado através do IE 5.5 teremos a figura 3. ASP.NET detecta o acesso à página do próprio WebService (ao contrário de um dos métodos dentro do serviço), e responde com uma página da informação sobre o serviço. Isto lhe mostra todos os métodos que ASP.NET encontrou na classe (neste caso, somente GetTime). Clique Invoke, e a página do teste chamará o método especificado e retornará os resultados (se VERDADEIRO). Note que os parâmetros estão passados na URL, e os resultados são retornados como XML através do protocolo HTTP. Note também que se deve abrir a página em uma maneira que passe pelo IIS, digitando em um UTL qualificado tal como o diretório virtual name/timeservice.asmx de http://localhost/your. Se simplesmente der um duplo clique, a página na visão do Explorer do disco rígido, irá passar por cima do IIS e ASP.NET e receber simplesmente o texto da página do asmx,.

Figura 4: Mostrando os segundos Descrição dos Web Services: Os arquivos SDL A fim permitir que

Figura 4: Mostrando os segundos

Descrição dos Web Services: Os arquivos SDL

A fim permitir que os programadores desenvolvam as aplicações dos clientes que usam este WebService, é preciso fornecer as informações necessárias durante os projetos e o processo de programação. O ASP.NET fornece um serviço descritivo. Quando se compila um WebService, o ASP.NET produz um arquivo que lista os protocolos suportados pelo serviço, pelos métodos fornecidos e pelos parâmetros requeridos por esse serviço. O arquivo é codificado em XML utilizando um vocabulário chamado Service Description Language (SDL). Pode-se considerar o arquivo SDL de um WebService como um contrato, porque lista as funcionalidades que o serviço é capaz e lhe informa como pedi-las. O arquivo SDL é um tanto complexo, assim para facilitar o entendimento foram separadas algumas parcelas para discutir os seus princípios; O elemento serviceDescription é a raiz do arquivo. Tudo dentro é parte da descrição do WebService. Existe um atributo que dá um nome ao WebService, neste caso, TimeService. A raiz contém dois tipos interessantes de sub-elementos. O primeiro é uma descrição do protocolo, que diz a um colaborador interessado no cliente que protocolos o serviço suporta e como codificar os dados do pedido e da resposta para esse protocolo. Qualquer pessoa ou ferramenta de desenvolvimento que olha o SDL saberá que o serviço nomeado TimeService pode ser alcançado através deste protocolo. O arquivo cheio de SDL contém também as entradas que dizem que pode ser alcançada através da operação HTTP Post e também através do Simple Object Access Protocol (SOAP) - um híbrido do HTTP/XML. Olhando dentro da descrição do protocolo, pode-se ver que o serviço contém um método chamado GetTime, que fica na URL especificada. O pedido requer um único parâmetro chamado ShowSeconds. O fato que usando a operação HTTP GET, a operação implica que ele está sendo passado para o formulário em forma de uma string. A resposta volta em XML, outra vez no formulário, como uma string. A segunda parte interessante no arquivo SDL é o elemento <schema> de W3C-standard. Este com a definição abstrata do serviço, sem consideração para como é alcançado em todo o protocolo particular ou uniforme onde vive. Podemos pensar nisso como uma definição de interface em um tipo de biblioteca; descrevendo uma série de métodos, mas não uma execução deles. Podemos ver que o meu arquivo de exemplo SDL descreve uma função nomeada GetTime, que requer um parâmetro booleano chamado ShowSeconds. Pode-se ver também que contém uma descrição separada do resultado do método GetTime, que volta em uma string.

Escrevendo Clientes WebService

O ASP.NET aceita três maneiras diferentes de empacotar o pedido entrante no HTTP: O HTTP GET, HTTP POST, e SOAP.

Caso 1: HTTP GET O serviço do Web aceitará um pedido através de um simples pedido HTTP GET com o parâmetro de ShowSeconds na string da URL. Vimos que o arquivo SDL descreve o suporte do WebService para este protocolo na seção precedente. Um exemplo de página Web que fornece o acesso a este pedido é mostrado na figura 5, e fornecido como o arquivo GetTimeThroughHttpGet.htm no código da amostra deste artigo. Quando o pedido alcança o servidor, ASP.NET analisa gramaticalmente os parâmetros da string da URL, cria o objeto de TimeService, e chama o método de GetTime.

Caso 1: HTTP GET O serviço do Web aceitará um pedido através de um simples pedido

Figura 5: Exemplo

Caso 2: HTTP POST

O serviço do Web aceitará um pedido após o pedido HTTP POST com o parâmetro de ShowSeconds em um controle da entrada. Os elementos separados < request > e < response > indicam aquele que faz o pedido do serviço, isto é, afixando o formulário, é uma operação separada para receber a resposta. Isto é como uma operação HTTP POST normalmente trabalha, assim não se preocupe com isso. O elemento < form > indica que a operação POST requer um formulário que com um controle da entrada nomeado ShowSeconds, que carregará este parâmetro. O arquivo é fornecido como GetTimeThroughHttpPost.htm. Quando o pedido alcança o servidor, ASP.NET cria o objeto TimeService, puxa os parâmetros dos controles do formulário, e chama o método de GetTime.

Caso 1: HTTP GET O serviço do Web aceitará um pedido através de um simples pedido

Figura 6: Enviando um pedido via HTTP POST

Caso 3: SOAP

O WebService aceitará um pedido do atendimento entrante através de um pedido HTTP POST que tenha toda sua informação codificada em um pacote do SOAP. O SOAP é um vocabulário de XML que descreve atendimentos da função e seus parâmetros. Um programa exemplo, mostrado em figura 7, que usa o SOAP para chamar o método GetTime do WebService. Isso usa o controle de transferência da internet da Microsoft fazer a comunicação real do HTTP. Note que, ao contrário dos dois exemplos precedentes, onde a

URL aponta o método dentro do serviço, a codificação do SOAP é dirigida à página do asmx que contém todos os métodos do WebService. O pacote do SOAP enviado ao servidor contém o nome da função e seus parâmetros, codificados em XML de acordo com um schema agreed-upon, como podemos ver no alto do controle de edição. Quando o pacote do SOAP alcança o servidor, ASP.NET reconhece, analisa gramaticalmente o nome do método e seus parâmetros fora do pacote, cria o objeto, e faz o atendimento.

URL aponta o método dentro do serviço, a codificação do SOAP é dirigida à página do

Figura 7: Cliente SOAP

A codificação XML do pacote do pedido varia um pouco do usado pelo artigo de Rob Caron no SOAP-Toolkit de agosto 2000 e nos exemplos que vêm com ele. O SOAP e .NET estão atualmente em muito desenvolvimento, assim que este tipo de divergência é a única a ser esperada.

Caso 4: Proxy Inteligente SOAP, Operação Simultânea.

O NET SDK gera as classes que o com o código necessário para um cliente SOAP de WebService em uma operação trivial. A ferramenta que faz isto é uma linha de comando chamada WebServiceUtil que vem com o NET SDK. Está também disponível no Visual Studio. Este programa lê a descrição do WebService de um arquivo SDL e gera um proxy para alcançá-los na linguagem especificada.

Pensando em duas versões uma síncrona e outra assíncrona. Na versão síncrona a classe do proxy herda da classe base System.Web.Services.Protocols.SoapClientProtocol com o código real. A classe do proxy com uma propriedade chamada Path, que o proxy herda da classe base. Esta propriedade especifica o URL do servidor a que o atendimento é dirigido. Isso contém um valor de opção que começa no arquivo original SDL, mas o programa de exemplo demonstra como pode mudar no "runtime" se necessário. O cliente chama o método nomeado no proxy chamando o método Invoke, que, outra vez, herdou da classe base. Este método então cria um pacote SOAP que com o nome e os parâmetros do método e emite-o ao servidor sobre o HTTP. Quando o pacote da resposta do SOAP volta do servidor, a classe base analisa-o gramaticalmente para fora do valor do retorno e retorna-o

ao proxy, que o retorna então ao cliente. O bloco dos atributos no nome da função (os caracteres entre os suportes de ângulo) contém a informação que diz à classe base como empacotar a chamada, tal como os nomes dos métodos e dos parâmetros. O Visual Studio.NET faz o uso extensivo dos atributos como uma maneira de passar a informação à funcionalidade pré-fabricada do código do sistema. Em alguns dias, isto seria feito provavelmente com as variáveis do membro da classe base onde seria difícil diferenciar os atributos runtime imutáveis daqueles que podem mudar durante a execução de programa.

ao proxy, que o retorna então ao cliente. O bloco dos atributos no nome da função

Figura 8: Cliente app

Case 5: Proxy SOAP Inteligente, Operação assíncrona.

O atendimento mais simples para um WebService pode facilmente demorar de 5 à 10 segundos para se completar. Não devemos deixar um usuário com uma interface congelada por mais do que um segundo ou dois segundos. Além de não podermos obstruir os atendimentos de um WebService da linha que segura a relação de usuário ao programa. É necessário que de algum modo fazer o atendimento de uma outra linha que possa esperar a resposta sem pendurar a relação com usuário, e em algum um tempo mais atrasado recuperar os resultados dessa linha e apresentá-los ao usuário. Até o momento, a maioria dos programadores foi obrigada a escrever o próprio código de infra-estrutura para lidar com esta situação. Este tipo de código é notoriamente complicado e por conseqüência caro. Agora, entretanto, desde que esta situação é quase universal, as classes inteligentes do proxy geradas por WebServiceUtil são equipadas com o código pré-escrito para segurá-la. Em vez de fazer uma chamada e uma obstrução até que isto termine, o programa pode chamar um método que transmite os dados do pedido ao servidor e retorna então, imediatamente. Mais tarde, em alguma hora conveniente, o programa pode chamar um outro método para colher os resultados retornados do servidor. Trabalhando com todo o servidor, não apenas aqueles que são escritos para suportar o acesso assíncrono. O proxy possui um método com o Beginmethodname conhecido, neste caso, o BeginGetTime. Sua lista do parâmetro começa com os parâmetros do método synchronous, neste caso, da variável booleana de ShowSeconds. Se não enviarmos nada (null), iniciamos a corrente de comunicação, emitindo para fora do pedido, e retornando imediatamente. O valor do retorno é um objeto do tipo IAsyncResult, é usado para conseguir o resultado posterior. Nos testes, foi introduzido um loop interativo longo na página asmx, contando apenas de uma a bilhão para simular uma operação longa. Em algum ponto anterior, se quisermos colher os resultados da operação, sendo necessário descobrir qual o tempo certo e o servidor irá retornar as informações. Podemos fazer isso chamando o método Endmethodname no proxy, neste caso, em EndGetTime, passando o IAsyncResult

começando pelo método Begin. Isso é como o código da infra-estrutura sabe que resultado deve ser retornado, como os clientes podem ter diversos pedidos simultâneos. O método final colhe o resultado e retorna-o. Mas como podemos saber quando a operação está completa e que resultados vamos receber? O objeto IAsyncResult contém um método usado para apenas esta finalidade, chamado IsCompleted, que retorna verdadeiro ou falso. Nossa linha da relação de usuário pode nomear periodicamente para saber concluída. Se chamarmos EndGetTime antes que a operação esteja terminada, obstruirá até que a operação faça no fato completo.