quinta-feira, 30 de setembro de 2010

Integrando aplicações Delphi Win32 com páginas WEB

Nesse post mostrarei como integrar aplicações Delphi Win32 com páginas Web. O exemplo será bem simples. Vamos imaginar que temos na web um log de erros unificados para todos os nossos clientes, e todas as instâncias de nosso software que estão sendo executadas. Imaginaremos que cada vez que ocorrer uma exception e um relatório de erro for gerado nós enviaremos esse relatório para a página na web, para que sejam armazenados em um banco de dados e possa ser lido ou analisado depois.

No nosso exemplo usaremos um campo memo para simular as mensagens de erro, assim podemos fazer várias mensagens diferentes.

Não usaremos banco de dados no nosso exemplo para não adicionar uma complexidade desnecessária a esse tutorial.

O que faremos é o seguinte: criaremos uma página php ou asp.net preparada para receber os dados de um formulário com um único campo: mLog. Não faremos uma página web para postar um formulário, faremos apenas a página que RECEBE o formulário.

Ao receber uma mensagem de log a página irá gravar a mensagem em um arquivo de texto, ler todos os registros do arquivo e mostrá-los na página em ordem inversa. Se você entrar na página esta não fará nada, apenas mostrará as mensagens.

Note que neste contexto você deveria mostrar apenas uma amostragem das mensagens, filtrar por cliente ou por sistema e esvaziar o arquivo periodicamente. Como nosso foco é apenas interagir com formulários não iremos nos ater a esses detalhes.

Primeiro: Crie o Formulário




//Versão em Asp.net
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Collections.Generic;

namespace RecebeLog
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            if (Request["mErro"] != null)
            {
                StreamWriter sw = new StreamWriter(Server.MapPath("/lista.txt"), true, System.Text.Encoding.UTF8, 2048);
                sw.WriteLine("---------------------------------------------------");
                sw.WriteLine(Request["mErro"]);
                sw.Flush();
                sw.Close();

            }

            if (!IsPostBack)
            {
                if (File.Exists(Server.MapPath("/lista.txt")))
                {
                    LerArquivo();
                }
                else
                {
                    File.CreateText(Server.MapPath("/lista.txt"));
                }
            }
        }

        protected void LerArquivo()
        {
            StreamReader sr = new StreamReader(Server.MapPath("/lista.txt"));
            Stack pilha = new Stack();

            while (!sr.EndOfStream)
            {
                string linha = sr.ReadLine();
                pilha.Push(linha);
            }
            sr.Close();

            Response.Write("Quantidade de Registros: " + ((int)(pilha.Count) / 2).ToString() + "

");

            while (pilha.Count > 0)
            {
                Response.Write(pilha.Pop() + "
");
            }
        }
    }
}

//fim



//Versão em PHP
<html>

<body>
<?
//#############################################################
//##                 ###
//## Autor:   Vitor Luiz Rubio                        ###
//## E-mail:   vitorrubio@gmail.com                    ###
//## Site:    http://www.vitorrubio.blogspot.com/     ###
//## Msn:    vitorrubio@gmail.com                    ###
//##                  ###
//##                 ###
//#############################################################

//aqui começa o script
//pega as variaveis por POST
$mErro = $_POST["mErro"];
$count = 0;
$count2 = 0;
$total = 0;
$conteudo = array("");

if($mErro != null)
{
 $fp = fopen("lista.txt", "a+");  // abre o arquivo para leitura e "append"
 fwrite($fp, "-------------------------------------------------------------------------------\r\n");
 fwrite($fp, $mErro."\r\n");   // grava no arquivo. Se o arquivo não existir ele será criado
 fclose($fp);       // fecha o arquivo
}

//ABRE O ARQUIVO TXT
$ponteiro = fopen ("lista.txt", "r");

if($ponteiro != null)
{

 //LÊ O ARQUIVO ATÉ CHEGAR AO FIM 
 while (!feof ($ponteiro)) {
   //LÊ UMA LINHA DO ARQUIVO
   $linha = fgets($ponteiro, 4096);
   
   array_push($conteudo, $linha);
   
   $count++;
 }//FECHA WHILE

 //fecha ponteiro para  o arquivo
 fclose ($ponteiro);

 $total = (int)($count -1) / 2;
 echo "<strong>Total de Ocorrências</strong><br/>".$total."<br/><br/>";

 while ($count2 < $count) {
   //LÊ UMA LINHA DO ARQUIVO
   $linha = array_pop($conteudo);
   //IMPRIME NA TELA O RESULTADO
   echo $linha."<br/>";
   
   $count2++;
 }//FECHA WHILE

}

?>

</body>
</html>
//fim


Segundo: Crie o Programa em Delphi

Usaremos para isso um formulário com um botão, um memo e um idHttp.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
  IdHTTP;

type
  TForm1 = class(TForm)
    IdHTTP1: TIdHTTP;
    Memo1: TMemo;
    Button1: TButton;
    edURL: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Texto: TStringList;
begin
  Texto := TStringList.Create;
  try
      Texto.Add('mErro='+Memo1.Lines.Text);
      //mErro = conteudo do memo1
      //use IdHTTP1.Post([URL], [mErro=[Mensagem]]);  //em um TStrings ou TStringList
      IdHTTP1.Post(edURL.Text, Texto);
  finally
      Texto.Free; //não esquecer do free
  end;  
end;

end.



Com isso, e um pouco de imaginação, você pode criar aplicações em qualquer linguagem que postem informações em páginas Web feitas também em qualquer linguagem. E se você usar o método GET na página WEB para ela retornar um XML, JSON ou YAML você já tem um webservice, rápido e simples de se implementar.

Experimente esse programa rodando em APACHE + PHP ou em IIS + Asp.Net e compile e rode o programa em Delphi. Adicione algumas mensagens e depois acesse a página para ver o que acontece. Veja o arquivo de texto. O diretório onde fica o arquivo de texto, ou pelo menos o próprio arquivo, deve ter permissão para que o PHP ou o Asp.Net escrevam nele.

Baixe o exemplo aqui

Have Fun ;)

2 comentários:

  1. Bom dia!
    Encontrei o seu blog, achei o exemplo interessante e resolvi perguntar:

    É possível montar o menu de uma aplicação em um formulário web, e este formulário chamar a execução, na estação-cliente, um programa de um projeto Delphi clássico?

    ResponderExcluir
  2. Veja bem, de acordo com os padrões de projeto e segurança, as integrações devem ocorrer no sentido aplicação win32 ==> internet, através de um soap webservice, rest, ou de um simples "post" em um formulário.
    Não existe maneira "correta" e "segura" de fazer isso que você precisa, e não há como garantir que funcione em todos os browsers. No IE você conseguirá fazer isso devido as vulnerabilidades dele. Poderá fazer isso com silverlight, flash ou através de um activex que execute o programa.

    Em .net é possível fazer uma aplicação que, banxando pelo IE ela funcione como uma espécie de plugin, baixando a aplicação automaticamente, instalando automaticamente e executando em um contexto seguro. Mas para que isso funcione no chrome e no firefox deve-se instalar um plugin.

    Sempre fuja desse tipo de abordagem a não ser que você esteja em uma intranet, ou que seu software seja um game. O nome da tecnologia que permite isso é ClickOnce.

    ResponderExcluir

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)