VB .NET -  Respondendo a requisições HTTP em sua aplicação (HttpListner)


 Neste artigo vou mostrar como podemos usar a classe HttpListner para responder a requisições HTTP em uma aplicação VB .NET.

Se você deseja que sua aplicação VB .NET esteja apta a responder a requisições HTTP e não sabe como fazer isso, então esse artigo é para você.

Antes da prática um pouco de teoria

A classe HttpListner fornece um ouvinte de protocolo HTTP simples que pode ser controlado via código fornecendo um mecanismo simples através do qual sua aplicação VB .NET poderá aceitar e responder requisições HTTP. 

Para poder usar os recursos dessa classe você deve seguir o seguinte roteiro:

1- Instancie um objeto HttpListner
2- Configure os prefixos de URI que o objeto HttpListener manipulará usando a propriedade Prefixes.


Um prefixo URI é uma seqüência de caracteres que representa a parte inicial de um URI, que consiste do tipo de esquema (como http: // ou https: //), um host e, opcionalmente, um caminho e uma porta. A propriedade Prefixs retorna uma coleção System.Net.HttpListenerPrefixCollection à qual você pode adicionar prefixos URI usando o método Add.
 
Cada prefixo deve terminar com uma barra (/), ou uma exceção System.ArgumentException será lançada. Se você especificar um prefixo de URL que já está sendo manipulado, uma exceção System.Net.HttpListenerException será lançada. Quando um cliente faz um pedido, uma requisição será tratada pelo ouvinte configurado com o prefixo que mais se aproxima da URL solicitada pelo cliente.

3- Inicie o objeto HttpListener chamando seu método Start. Você deve chamar Start antes do objeto HttpListener poder aceitar e processar solicitações HTTP;

4-  Aceite solicitações do cliente usando o método GetContext do objeto HttpListener. O método GetContext irá bloquear a thread de chamada até que uma solicitação seja recebida e, em seguida, retornará um objeto System.Net.HttpListenerContext. Como alternativa, você pode usar os métodos BeginGetContext e EndGetContext para ouvir solicitações em um segmento de thread-pool.

Quando um pedido é recebido, o delegate System.AsynchCallback especificado como o argumento para o método BeginGetContext será chamado e passa o objeto HttpListenerContext. Independentemente da forma como é obtido, o objeto HttpListenerContext implementa três propriedades somente leitura críticas para o tratamento de um pedido de cliente:

- A propriedade Request devolve um System.Net.HttpListenerRequest através do qual você pode acessar detalhes da solicitação do cliente.
- A propriedade Response devolve um System.Net.HttpListenerResponse através do qual você pode configurar a resposta para enviar para o cliente.
- A propriedade User devolve uma instância de um tipo que implementa System.Security.Principal.IPrincipal, que você pode usar para obter informações de identidade, autenticação e autorização sobre o usuário associado ao pedido.

5- Configure a resposta HTTP através dos membros do objecto HttpListenerResponse acessível através da propriedade HttpListenerContext.Response;

6- Envie a resposta chamando o método Close do objeto HttpListenerResponse;

7- Depois de concluir o processamento de solicitações HTTP, chame o método Stop no objeto HttpListener para parar de aceitar mais solicitações e interromper o ouvinte. Chame o método Close para desligar o objeto HttpListener, que esperará até que todas as solicitações pendentes tenham sido processadas ou chame o método Abort do objeto HttpListener para não aguardar pedidos a serem completados.

Nota:  A classe HttpListner exige direitos a nível de administrador do sistema.

Ufa...

Agora vamos ao que interessa:  o código...

No exemplo deste artigo vamos demonstrar como usar a classe HttpListener para processar solicitações HTTP.

O exemplo começa escutando a ouvir para cinco requições simultaneamente usando o método assíncrono BeginGetContext e manipula a resposta para cada solicitação chamando o método RequestHandler.

Cada vez que uma solicitação é tratada, uma nova chamada é feita para BeginGetContext para que você sempre tenha a capacidade de
processar até cinco solicitações.

Para abrir uma conexão com o exemplo do seu navegador, digite a URL :

e você verá a resposta do manipulador de requisições apropriado.

Recursos Usados

Criando o projeto Windows Forms

Abra o VS 2017 Community e crie um novo projeto (File-> New Project) usando a linguagem VB .NET e o template Console Application.

Informe um nome a seu gosto. Eu vou usar o nome Vbn_HttpListner;

Abra o arquivo Module1.vb e a seguir declare os seguintes namespaces no formulário:

Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Threading

No início do módulo declare as váriaveis a seguir:

 ' Configura o mumero maximo de requisições que podem ser tratadas concorrentemente
Private maxRequestHandlers As Integer = 5
' Usa um inteiro para atribuir cada requisição HTTP a um identificador unico
Private requestHandlerID As Integer = 0
' Cria um objeto HttpListener que fornece todos os recursos para receber e processar requisições HTTP
Private listener As HttpListener

A seguir no método Main() inclua o código abaixo:

    Sub Main()
        ' Se o recurso não for suportado encerra o programa
        If Not HttpListener.IsSupported Then
            Console.WriteLine("Você precisa estar executando no ambiente do Windows" &
                              " XP SP2, Windows Server 2003, ou superior para criar um HttpListener.")
            Exit Sub
        End If
        ' Cria um HttpListener.
        listener = New HttpListener
        ' Configura os prefixos URI que irão mapear para o HttpListener.
        listener.Prefixes.Add("http://localhost:19080/Macoratti.net/")
        listener.Prefixes.Add("http://localhost:20000/VbNet/")
        ' Inicia o HttpListener antes de atender as requisições 
        Console.WriteLine("Iniciando o servidor HTTP")
        listener.Start()
        Console.WriteLine("Servidor HTTP iniciado")
        Console.WriteLine(Environment.NewLine)
        ' Cria um numero de tratadores de requisições assincronas
        ' ate a configuração maxima definida, cada um com identificador unico
        For count As Integer = 1 To maxRequestHandlers
            listener.BeginGetContext(AddressOf RequestHandler,
                                     "RequestHandler_" & Interlocked.Increment(requestHandlerID))
        Next
        ' Aguarda pela ação do usuário para parar o HttpListener.
        Console.WriteLine("Pressione Enter para parar o Servidor HTTP.")
        Console.ReadLine()
        ' Para de aceitar novas requisições
        listener.Stop()
        ' Termina o HttpListener sem processar as requisições atuais
        listener.Abort()
        ' Aguarda...
        Console.WriteLine(Environment.NewLine)
        Console.WriteLine("Processamento completado. Pressione Enter.")
        Console.ReadLine()
    End Sub

 

O código acima define as URI que serão mapeadas para o HttpListner e define o método RequestHandler para tratar a resposta às requisições.

O código do método RequestHandler pode ser visto abaixo:

    'Este método processa de forma assincrona requisições individuais
    Private Sub RequestHandler(ByVal result As IAsyncResult)
        Console.WriteLine("{0}: Ativado.", result.AsyncState)
        Try
            ' Obtem o HttpListenerContext para a nova requisição
            Dim context As HttpListenerContext = listener.EndGetContext(result)
            Console.WriteLine("{0}: Processando requisição HTTP de {1} ({2}).", result.AsyncState,
                              context.Request.UserHostName, context.Request.RemoteEndPoint)
            ' Cria uma resposta usando um StreamWriter 
            Dim sw As New StreamWriter(context.Response.OutputStream, Encoding.UTF8)
            sw.WriteLine("<html>")
            sw.WriteLine("<head>")
            sw.WriteLine("<title>Macoratti .Net - Quase tudo para VB .NET</title>")
            sw.WriteLine("</head>")
            sw.WriteLine("<body>")
            sw.WriteLine("VB .NET 2017 : " & result.AsyncState)
            sw.WriteLine("</body>")
            sw.WriteLine("</html>")
            sw.Flush()
            ' Configura a resposta
            context.Response.ContentType = "text/html"
            context.Response.ContentEncoding = Encoding.UTF8
            ' Fecha a resposta para enviá-la ao cliente
            context.Response.Close()
            Console.WriteLine("{0}: resposta HTTP enviada.", result.AsyncState)
        Catch ex As ObjectDisposedException
            Console.WriteLine("{0}: HttpListener liberado--shutting down.", result.AsyncState)
        Finally
            ' Inicia outro manipulador a menos que o HttpListener esteja fechado
            If listener.IsListening Then
                Console.WriteLine("{0}: Criando um novo tratador de requisição.", result.AsyncState)
                listener.BeginGetContext(AddressOf RequestHandler, "RequestHandler_" &
                    Interlocked.Increment(requestHandlerID))
            End If
        End Try
    End Sub

Neste código estamos definindo a resposta às requisições mapeadas para os endereços URIs.

Executando o projeto teremos o seguinte resultado:

1- Resposta para requisições em : http://localhost:19080/Macoratti.net/

2- Resposta para requisições em : http://localhost:20000/VbNet/

Temos assim um servidor respondendo a requisições usando o HttpListner no VB .NET.

Pegue o projeto completo aqui :  Vbn_HttpListner.zip

Sabendo, amados irmãos, que a vossa eleição é de Deus;Porque o nosso evangelho não foi a vós somente em palavras, mas também em poder, e no Espírito Santo, e em muita certeza, como bem sabeis quais fomos entre vós, por amor de vós.
1 Tessalonicenses 1:4,5

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ?

 

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

 

Referências:


José Carlos Macoratti