Share Button

Um servidor Datasnap é na excência um servidor HTTP nativo…. SIM é possível implementar um HTTP Server no mesmo servidor de Datasnap.

1. Criar um Servidor Datasnap padrão

Ao criar um Servidor DataSnap (pelo expert do Delphi), várias UNITs são adicionadas.
Se observar a UNIT que nos importa aqui é a WebModuleUnit1;

Toda vez que é feito uma chamada a um recurso na porta do HTTP do servidor e for um arquivo será executado o evento “WebModuleBeforeDispatch” o que permite inserir códigos que execute algum procedimento diferente daqueles previstos.

No nosso caso queremos chamar um arquivo externo “index.html”, “jquery.js”, “minhafoto.png”, “my.pdf”… enfim, um arquivo que esteja armazenado na pasta base do site “www”.

2. Inserindo código para suporte ao HTTP Server

Tentando facilitar o trabalho introduzi um novo componente através da  “UNIT DataSnap.HTTPModule;”


// incluir na USES
uses ... DataSnap.HTTPModule...
..

// Incluir um Private para o objeto 
   {Componente que implementa o código de resposta para o HTTP Server - por Amarildo Lacerda}
   FHttpModule:TDataSnapHTTPModule;
..

// alterar o Create para
procedure TWebModule1.WebModuleCreate(Sender: TObject);
begin
  {
     incia o componente indicando a pasta onde será hospedado a URLBase para oa arquivos de HTTP Server
     [pastaBase]/index.html
  }
  FHttpModule:=TDataSnapHTTPModule.Create(self);
  FHttpModule.URLPath := ExtractFilePath(paramStr(0)) + 'www';
  ForceDirectories(FHttpModule.URLPath);

  FServerFunctionInvokerAction := ActionByName('ServerFunctionInvokerAction');
end;

// alterar 
procedure TWebModule1.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  { Redireciona a chamada HTML, JavaScript ou outro tipo de arquivo que exista na pasta padrão - por Amarildo Lacerda}
  FHttpModule.GoURLDocument(Request, Response, Handled);
  if Handled then
    exit;


  if FServerFunctionInvokerAction <> nil then
    FServerFunctionInvokerAction.Enabled := AllowServerFunctionInvoker;
end;

Pronto… Seu Servidor Datasnap já sabe como responder como um HTTP Server nativo.

Digite: http://localhost:8080 – e o servidor irá procurar por uma página padrão: index.html

Código de Exemplo: Datasnap.HttpModule

Share Button

Para aqueles momentos que quero varrer todos os componetes que estão no FORM para pegar quem são e aplicar um operador   AS que tal usar um metódo anônimo para isto….

Forma tradicional

A forma tradicional de se varrer todos os componentes que estão sobre responsabilidade do FORM é fazer um loop com FOR e avaliar um-a-um até encontrar o que se deseja.


var &nbsp;i:integer;
begin
     for i := 0 to FormX.ComponentCount-1 do
     begin
           if FormX.Components[i] is TQuery then   // quero pegar so as TQuery
           with FormX.Components[i] as TQuery do
           begin   
               close;   // fechar a TQuery
           end;
     end;
 
end;

 

Loop de Componentes com Anonimous Methods

Utilizando “Anonimous Methods” é um modelo não tradicional de olhar a mesma questão. Entender a estrutura de um “Anonimous Method” pode simplificar muitas operações de codifição do dia-a-dia e como exemplo de fundo vamos varrer os componentes dos formulários…

  • Criando um HELPER para separar a lógica (o LOOP)
    type
      TComponentHelper = class Helper for TComponent
    
      public
        procedure ComponentsLoop(AProc: TProc&lt;TComponent&gt;; AChild: boolean = false);
      end;
    
    procedure TComponentHelper.ComponentsLoop(AProc: TProc&lt;TComponent&gt;; AChild: boolean = false);
    var
      i: integer;
    begin
      if assigned(AProc) then
        for i := 0 to ComponentCount - 1 do
        begin
          AProc(Components[i]);
          if AChild and (Components[i].ComponentCount &gt; 0) then
            Components[i].ComponentsLoop(AProc, AChild);
        end;
    end;
    
  • Executando o LOOP utilizando o método anônimo do HELPER
    
    procedure TForm39.Button1Click(Sender: TObject);
    begin
      Memo1.Lines.Clear;
      ComponentsLoop(
        Procedure(AComp: TComponent)
        begin
          // fecha todos os TDataset  (TQuery)
          if AComp is TDataset then
            with AComp as TDataset do
                close;
    
        end, false);
    
    end;
    
    

 

Usando  Anonimous LOOP para um TList (genérico)

Quando vezes precisou fazer um loop em um TList….

  • Implementando um LOOP “anonimous” para o TList na classe HELPER
    procedure TComponentHelper.ListLoop(AList: TList; AProc: TProc&lt;TObject&gt;);
    var
      i: integer;
    begin
      for i := 0 to AList.Count - 1 do
        AProc(AList[i]);
    end;
    
    
  • Aplicando o LOOP “anonimous” em um TList
    procedure TForm39.Button3Click(Sender: TObject);
    var
      FList: TList;
    begin
      memo1.Lines.Clear;
      FList := TList.create;
      try
        PopularALista(FList);
    
        // fazer um LOOP usando Anonimous
        ListLoop(FList,
          procedure(AObj: TObject)
          begin
            memo1.Lines.Add( AObj.ClassName );
          end);
    
      finally
        FList.Free;
      end;
    end;
    
    

Parece Simples !!! Quantas vezes precisou escrever um LOOP em um TDataset (aka TQuery, TClientDataset)???

Código Exemplo  Helper para TDataset