sábado, 4 de agosto de 2012

Explorando o NeonMika.Webserver - Parte 1

Hoje teria que continuar trabalhando no projeto da empresa, o SimOp, mas por um erro meu não fiz o upload do arquivo certo e agora não estou com a versão do código mais atualizada então não posso trabalha nele, por isso resolvi continuar desbravando o NeonMika.WebServer.

O que me interessa a princípio é fazer uma aplicação simples com a comunicação pela internet. Simples não quer dizer que seja fácil! O que eu espero é ter uma estrutura de manipulação da placa (ler o ADC, ler e escrever as portas IO, etc) que é perfeito para quem está desenvolvendo. No nosso caso, caros amigos leitores desse blog, podemos parar por aqui, a final de contas se você quiser mudar qualquer configuração basta recompilar o código e embarcar que estará tudo novo!

O grande problema é que 99% dos robsistas param por aqui, mas para aplicações mais comerciais isso não basta, se não vai se tornar um produto que eu costumo chamar de "house made" como muita coisa nacional que se comercializa apenas no mercado brasileiro por rasões óbvias. Existem muitos exemplos disso - geralmente in nichos de mercado gerados por lei - como o caso do controle de acesso homologado pelo ministério do trabalho existem modelos importados excelentes, mas como não são homologados não servem para empresas e nós acabamos sendo vitimas disso.

Outro exemplo forte nessa área são os receptores via satélite, dezenas de modelos para mercado nacional (Tecsys, Amplimatic, Plasmatic, Limon etc etc etc... ) que estão ainda muito longe do padrão dos aparelhos Azbox, Az América, NewGen que são nomes genéricos de modelos fabricados obre encomendada para as TV por assinatura  ( Sky, NET e etc...).

Em função de toda essa fama, um dos meus objetivos antes de morrer será fabricar algo nacional que não seja mais um produto no mercado sem visibilidade mas sim algo que possa competir com os modelos que estão no mercado, seja qual segmento for...

Então, continuando a explanação, exite a necessidade de algo mais profissional para aplicação com Internet dizendo respeito a configuração do dispositivo e afins. Vendo as soluções do mercado pode-se tirar como base os pequenos dispositivos que estruturam a rede de internet que necessitam de configuração (Roteadores, Access Point's), eles utilizam um pequeno servidor interno para permitir configurar o dispositivo, o que é uma solução bem interessante uma vez que não necessita de mais portas além da porta de Ethernet que já está disponível.

No caso do Netduino Plus, existem 3 formas facilitadas (facilitadas porque não precisa de hardware externo) para realizar a configuração:
  • Através de um arquivo no cartão microSD (necessita da remoção do cartão);
  • Através da porta USB (necessita disponibilizar a porta e fazer um "miguer");
  • Através de um servidor web;
 Sem dúvida  o servidor web é mais interessante que as demais soluções por motivos não tão óbvios assim. Posso destacar o hábito como um forte aliado para escolha, quem configura dispositivos na rede já está acostumado com o processo pela página interna do dispositivo (um facilitador) e além disso não é necessário deixar disponível a porta USB para alguém tentar colocar um cabo nela e acabar por travar a execução do seu código e tão pouco deixar o cartão microSD disponível para ser removido (não precisa tratar a remoção do cartão acidental).

Por fim, destaco ainda, que através do servidor web na placa é possível fazer uma pequena depurção de código e apresentar todos os dados do cartão microSD, mais a frente pretendo detalhar uma maneira de fazer isso transparente, escrevendo um arquivo de log de eventos no cartão microSD e depois apresentando-o através da página do servidor html interno.

Outra vantagem que pode ser destacada é a facilidade de acesso e configuração remota da placa. Se a aplicação for colocada em um local de dificil alcance torna-se mais rápido configurá-la via Ethernet.

Por todos esse motivos não tem porque não utilizar o servidor web no Netduino Plus e agora podemos entrar diretamente no NeonMika.WebServer e como vamos utilizá-lo. Particularmente, não conheço muito de internet e protocolos de rede por isso vou dar uma explicação ao meu ver do NeonMika, até porque tive muita dificuldade em encontrar informação sobre o projeto.

Aqui vão algumas dicas para você que está começando nesse negócio de WebServer com o NeonMika, porque eu apanhei muito hoje para colocar esse código para rodar. Primeiro, faça download da versão mais atual do NeonMika.Webserver, se estiver usando o .NET MF 4.2, atualize o primeiro projeto da solução para o .NET MF 4.2, depois atualize os outros em sequência. Feito isso dê uma compilada no projeto, vãoa parecer alguns erros ligados a identificação do AnalogInput, altere para SecretLabs.NETMF.Hardware.AnalogInput todos.

Agora, quando você tentar debugar, vai ter um erro: "The project 'NeonMika.Webserver' cannot be referenced.". Para resolver abara o projeto do NeonMika.Webserver tente uma vez deugar usando o emulador depois retorne para USB > NetduinoPlus_NetduinoPlus.

Para achar o IP que foi lançada a aplaca na rede veja na janela Output, tem algo escrito como: "Webserver is running on 192.168.5.100 /// DHCP: False". Pronto está rorando, agora basta acessar a página pelo IP que você verá a página inicial, ou não, aqui em casa ele estava subindo numa subrede diferente aqui é 192.168.1.xxx não 192.168.xxx.xxx!

Bom, na minha rede isso acontece porque eu deixo o IP fixo e mando o DHCP gerar IP's fora da rede para confundir qualquer favelado que more na vizinhança se ele tentar derrubar a minha rede sem fios para acessá-la (acredite isso acontece...). De qualquer forma, demorei não mais que 1 hora procurando onde se colocava o IP que teoricamente seria fixo, então comecei a entender o código parindo do construtor Server em Server.cs. Descobri que não existe um lugar para colocar o IP fixo! Então fiz uma pequena modificação na função, e ficou assim:

///
/// Creates an instance running in a seperate thread
///
/// OutputPort to indentify
/// The port to listen
///
/// IP
/// Mask
/// GateWay
public Server(OutputPort ledPort, int portNumber = 80, bool DhcpEnable = false,
                string ipAddress = "", string subnetMask = "", string gatewayAddress = "")
{
    var interf = NetworkInterface.GetAllNetworkInterfaces()[0];

    if (DhcpEnable)
    {
        interf.EnableDhcp();
        interf.RenewDhcpLease();
    }
    else
    {
        //New to fix
        interf.EnableStaticIP(ipAddress, subnetMask , gatewayAddress );

    }

    Debug.Print("Webserver is running on " + interf.IPAddress.ToString() + " /// DHCP: " + interf.IsDhcpEnabled.ToString());

    this._PortNumber = portNumber;
    _OnboardLed = ledPort;
    ResponseListInitialize();

    _ListeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    _ListeningSocket.Bind(new IPEndPoint(IPAddress.Any, portNumber));
    _ListeningSocket.Listen(4);

    var webserverThread = new Thread(WaitingForRequest);
    webserverThread.Start();
}
E naturalmente, você terá a opção de declarar um IP fixo em Program.cs:

bServer = new Server(PinManagement.OnboardLED, 80, false, "192.168.1.41", "255.255.255.0", "192.168.1.1");
Continuando, não foi só isso que modifiquei, na verdade, como o meu interesse era usar a página no cartão microSD e nada mais justo que ver funcionando - e isso me tomou tempo - em especial porque não conseguia acertar de maneira alguma o local onde o arquivo fica alojado para ser chamado, muito embora os métodos estivessem todos corretos, o caminho tinha problemas com a barras "\" e "/".  Assim eu tive que modificar a fonção SendResponse para que ela faça a inversão das barras do endereço e busque dentro do cartão o local correto.

public override bool SendResponse(RequestReceivedEventArgs RequestArguments)
{
           
    //System.Text.StringBuilder.Replace(char, char)
    StringBuilder filePath = new StringBuilder();
                           
    filePath.Append(@"\SD\");
    filePath.Append(RequestArguments.Request.URL);
    filePath.Replace(@"/",@"\");


    //string filePath = @"\SD\shali2.jpg";

    //File found check
    try
    {
        if (!File.Exists(filePath.ToString()))
        {
            Send404_NotFound(RequestArguments.Client, "Não encontrado:" + filePath.ToString());
            return false;
        }
    }
    catch (Exception ex)
    {
        Debug.Print(ex.ToString());
        return false;
     ..... continua ....

Se você estiver modificando na versão atual do NeonMika.Webserver você vai notar que a função
Send404_NotFound também foi modificada. Tive que modificá-la porque simplesmente não estava funcionado e, por outro lado, ela não permitia a depuração na página dizendo o endereço ou uma mensagem personalizada. Então a função ficou assim:

///
/// Sends a 404 Not Found response
///
protected void Send404_NotFound(Socket Client, String Message = null)
{

    Debug.GC(true);
    if (Client != null)
    {
        string header = null;

        if (Message != null)
        {
            header = "\n\n\n

HTTP/1.1 404 Not Found

\n"
+ Message + "
\n\n\n";
        }
        else
        {
            header = "\n\n\n

HTTP/1.1 404 Not Found

\nNeonMika.Webserver is sorry...
\n\n\n"
;
        }
               
        Client.Send(Encoding.UTF8.GetBytes(header), header.Length, SocketFlags.None );
    }
}
}

Com isso já dava para utilizar o NeonMika.WebServer e colocar uma página no cartão SD para testar. Com o intuito de testar eu busquei na internet um template de site que fosse relativamente completo com imagens e tudo mais e subpáginas e consegui ter um bom grau de sucesso, muito embora as imagens não tenham sido carregadas ainda... mas assim que consertar isso vou postar a segunda parte dessa análise do servidor NeonMika.





Para fazer download do código NeonMika com as modificações clique aqui.
Para fazer download da página para testar no cartão MicroSD clique aqui.

Um comentário:

  1. Muito legal, Obrigado pela explicação, nunca usei o NeonMika, vamos ver o que dá..

    ResponderExcluir