Atualização em Agosto de 2020: Esse post é antigo, foi escrito em 2012. Tal conteúdo não é mais aplicável nos tempos de hoje. Quer verificar a disponibilidade de um API, qualquer tipo? Ate mesmo Back-end Services? Crie um Health Check e configure alertas caso nao esteja disponivel.
Olá Pessoal!
Hoje eu quero escrever um Post útil, de uma tarefa que tive que fazer aqui na empresa. Ela consiste de criar uma página para verificar todos os serviços que estão disponíveis dos nossos Sistemas de forma centralizada. A partir de todos os endereços dados.
Ou seja eu me deparei com o seguinte problema:
Como verificar a Disponibilidade de um Serviço WCF ou WebService de forma genérica, passando por parâmetro apenas o EndPoint ou o Endereço do WebService que é uma URL.
Antes de mostrar o meu código, darei uma breve explicação sobre ele, dividido em duas partes: WebService e WCF.
Validando um WebService:
O Web Service é relativamente fácil. Considerando que ele é uma URL. E quando você adiciona referência de um Web Service, onde o Visual Studio constrói suas classes de Proxys? Pelo WSDL é claro! Quando você dá Add Web Reference no Project ele busca esse endereço e mostra para você todos os dados daquele Web Service. Até ai estou ensinando padre à rezar, isso é claro para todos que desejam implementar o código desse Post =D
Considerando que o WSDL é um XML, o que precisariamos fazer é: Criar um método dado uma string como parâmetro, adicionar a QueryString “?wsdl” e verificar se a saida é um XML. Simples assim, foi exatamente o que eu fiz. Obviamente precisamos validar Exceptions como por exemplo TimeOut “Se o serviço estiver fora, talvez tenhamos esse resultado como resposta =D”
Só uma observação: O Servidor Web pode retornar por exemplo “Service Busy” ou “Forbidden” ou qualquer outra saída de HTTP Code, diferente do Sucess “2xx”.
Validando um WCF:
Aqui o negócio fica mais difícil. Pensei em várias formas de fazer e também realizei várias pesquisas. Como o WCF o Binding dele não é necessariamente HTTP, podendo ser wsHttpBinding, netMsmqBinding, netNamedPipeBinding… Etc. Então teríamos que validar o serviço de fato.
Alguns programadores me sugeriram:
- Dar um ping no servidor “Acho que não preciso explicar porque descartei isso né? ;)”
- Adicionar um serviço do Tipo HelloWorld em todos “Fucionaria, porém eu não posso alterar milhões de serviços que já estão em produção :(“
- Tem também uma terceira opção que parece ser do Próprio Framework, mas não temos referências boas na internet. Então nem implementei.
Depois eu comecei a pensar e você também pensará comigo: Se o WebService quando eu faço Add Web Reference ele busca o WSDL para construir o Proxy. Como é feito o Add Service Reference do WCF? Era exatamente esse ponto que eu consegui resolver! O Meu amigo o Arquiteto de Software Rafael Tolotti “http://rafatolotti.wordpress.com/” Me disse o seguinte: Por default quando você cria um serviço WCF ele essas chaves no WebConfig: Esse EndPoint: <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” /> E esse Behavior: Que por sua vez depende da chave: <serviceMetadata httpGetEnabled=”true” /> E pra que serve essas chaves? Para justamente quando você tiver um serviço diferente de HTTP que não tenha a saida do WSDL por default, o WCF cria-la! Assim quando você der o Add Service Reference ele procurara esse endereço e achará o WSDL. Por exemplo, esse endereço de Serviço: net.tcp://meuservidor.com.br/ServicoPedido/Pedidos.svc O WSDL dele seria: http://meuservidor.com.br/ServicoPedido/Pedidos.svc?wsdl Se você tiver com aquele Behavior e o EndPoint criados, ele funcionará. Obviamente você terá que ver se a configuração está certa do seu servidor, para ver se está funcionando. Se for o IIS do Visual Studio funcionará ! Ou seja, antes de você criar o endereço para verificar, basta mudar o net.tcp para http. E pronto.
Segue o Código:
public class CheckService {
private string _endereco;
public String Endereco {
get {
return _endereco;
}
set {
_endereco = value;
}
}
private string _descricao;
public string Descricao {
get {
return _descricao;
}
set {
_descricao = value;
}
}
private string _erro;
public string Erro {
get {
return _erro;
}
set {
_erro = value;
}
}
}
public void PreencherStatusServico(POCO.CheckService oCheckService) {
string strRequestWSDL;
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(oCheckService.Endereco);
request.Timeout = 5000;
try
{
WebResponse oWebResponse = request.GetResponse();
strRequestWSDL = oCheckService.Endereco + "?wsdl";
oWebResponse = WebRequest.Create(strRequestWSDL).GetResponse();
if (!oWebResponse.ContentType.ToUpper() == "TEXT/XML; CHARSET=UTF-8")
{
oCheckService.Erro = "Erro: Não é xml válido.";
}
}
catch(TimeoutException ex)
{
oCheckService.Erro = "Erro de TimeOut: " + ex.Message;
if (ex.InnerException != null & amp; & amp; ex.InnerException.Message != null)
{
oCheckService.Erro += "<br />Inner Exception: " + ex.InnerException.Message;
}
}
catch(Exception ex)
{
oCheckService.Erro = "Erro: " + ex.Message;
if (ex.InnerException != null & amp; & amp; ex.InnerException.Message != null)
{
oCheckService.Erro += "<br />Inner Exception: " + ex.InnerException.Message;
}
}
}
É isso ai Pessoal, qualquer dúvida é só deixar um comentário.
Abraços!
Fala Marcos,
Muito bom o post. Estou implementando algo assim e vou utilizar-lo..valeu.
Gostaria de saber de você, se realmente vale a pena utilizar o WCF para criação de serviços ou devo continuar usando webservices(asmx) pois são bem mais simples de ser executado. Preciso saber qual dos dois é mais rápido e qual gerar a menor quantidade de dados na resposta.
valeu!
Opa! Boa Tarde Naldo!
Obrigado pelo elogio ^^ Fiz um programinha na empresa que usei esse exemplo que coloquei aqui no Blog hehe
Com toda certeza o WCF sem sombras de dúvidas.
O WCF é um Web Service (ASMX) – Porém mais avançado e com muito mais possibilidades. Por exemplo: Com o ASMX você tem saída apenas HTTP certo?
Com WCF você pode ter um serviço que possua um endpoint apenas wsHttpBinding que funcionaria da mesma forma. Mas tem outras opções também.
Mas você falou algo interessante: Você quer velocidade. Então eu te digo para você usar o WCF com o endpoint com o tipo de binding netTcpBinding
Assim ele usará apenas TCP IP para as comunicações. É super rápido! Muitíssimo mais rápido do que os antigos ASMX 😉
Eu que agradeço! =D
Opa…valeu msm..vou testar aqui..você indica algum site ou livro pra iniciar em WCF?
Beleza 😉
Eu gosto muito dos livros de certificação:
http://www.amazon.com/MCTS-Self-Paced-Training-Exam-70-503/dp/0735625654/ref=sr_1_2?ie=UTF8&qid=1325849541&sr=8-2
Eu tenho 4 desses:
WCF 3.5 – Te mandei o Link
Framework 2.0
ASP.NET 3.5
ASP.NET 4.0
São livros muito bons. São em inglês essa é a unica questão. Mas vale a pena !
Inclusive você pode baixa-los em PDF, só da uma procurada no Google que você acha! =D