Artigo Clube Delphi 86 - SOAP - Aprenda técnicas avançadas em um exemplo passo a passo- Parte 2

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (1)  (0)

Nesta edição, veremos gerenciamento de sessão, envio de arquivos via SOAP, compactação e muito mais.

Esse artigo faz parte da revista Clube Delphi Edição 86. Clique aqui para ler todos os artigos desta edição

SOAP

SOAP - Aprenda técnicas avançadas em um exemplo passo a passo- Parte 2

 

Na primeira parte deste artigo, começamos a construir nosso disco virtual, um aplicativo onde o usuário poderá enviar arquivos para um servidor remoto, listá-los e recuperá-los posteriormente. Criamos a interface gráfica do cliente, vimos um pouco sobre autenticação com SOAP, exceções remotas, envio e recebimento de SOAP Headers e como rastrear as chamadas ao servidor. Nesta edição, veremos gerenciamento de sessão, envio de arquivos via SOAP, compactação e muito mais.

 

Gerenciamento de sessão

O mecanismo de autenticação que implementamos funciona, mas não está completo. Ele retorna sempre o mesmo identificador de sessão, definido de forma hard-coded no código do servidor, o que não é, obviamente, uma solução segura. Precisamos gerar um valor que seja único entre todos os usuários que podem vir a se autenticar.

Aqui temos um problema: Web Service são por natureza stateless, o que significa que nenhuma informação é persistida entre as requisições processadas. Mas o servidor precisa “lembrar” dos identificadores gerados, para poder comparar com os fornecidos pelos clientes. Como conseguir isso? Uma alternativa é controlar sessões.

A implementação do protocolo SOAP disponível com o Delphi não fornece nenhum mecanismo de persistência nativo. Dessa forma, precisamos criar um. Atente então para um detalhe importante: nosso Web Service reside em uma DLL ISAPI, que é carregada pelo IIS na primeira requisição recebida pelo servidor.

Essa DLL fica no contexto do processo DLLHost.exe, também conhecido como COM Surrogate. E ela ficará lá, em memória, até ser descarregada, como você fez algumas vezes ao longo desse artigo. Mas Web Service não são statesless?

Sim, são! Abra novamente uDiscoVirtualImpl e observe a classe TDiscoVirtual. Esse é o nosso Web Service. É essa classe que é criada e destruída automaticamente a cada execução remota. O resto da unit permanece intacto, carregado na memória. Confuso? Vamos implementar para você entender melhor.

Selecione o projeto do servidor e adicione a ele um Data Module. Chame-o de “TdmSession” e salve o arquivo com o nome “uSessionDataModule”. Clique agora no menu Project e escolha View Source. Remova a seguinte linha de código:

 

Application.CreateForm(tdmSession, dmSession);

 

Fizemos isso porque criaremos manualmente o Data Module. Adicione um ClientDataSet. Dê um duplo clique sobre ele para abrir o editor de campos e insira os seguintes Fields:

1.      SessionID: Tipo String, tamanho 38;

2.      LastAccess: Tipo DateTime;

3.      UserName: Tipo String, tamanho 10;

4.      UserID: Tipo Integer.

Clique de direita sobre o ClientDataSet e escolha Create DataSet. Pronto, já temos um DataSet para armazenar os identificadores de sessão gerados para cada usuário. Vamos então criar alguns métodos para gerenciar sessões. Adicione as linhas da Listagem 1 na seção public da classe TdmSessions:

 

Listagem 1. Métodos de TdmSessions

function NewSession(const UserID: Integer;

  UserName: string): string;

procedure RemoveSession(const SessionID: string);

function IsValidSession(

  const SessionID: string): Boolean;

function GetUserID(const SessionID: string): Integer;

procedure UpdateLastAccess(const SessionID: string);

 

Implemente agora todos esses métodos (Ctrl+Shift+C) com o código da Listagem 2.

 

Listagem 2. Métodos de manipulação de sessão

function TdmSessions.NewSession(const UserID: Integer;

  UserName: string): string;

var

  SessionID: TGUID;

begin

  CriticalSection.Enter;

  try

    if not cdsSessions.Active then

      cdsSessions.Open;

 

    CreateGUID(SessionID);

    Result := GuidToString(SessionID);

 

    cdsSessions.Insert;

    cdsSessionsSessionID.AsString := Result;

    cdsSessionsStartDateTime.AsDateTime := Now;

    cdsSessionsLastAccess.AsDateTime := Now;

    cdsSessionsUserName.AsString := UserName;

    cdsSessionsUserID.AsInteger := UserID;

    cdsSessions.Post;

  finally

    CriticalSection.Leave;

  end;

end;

 

function TdmSessions.IsValidSession(

  const SessionID: string): Boolean;

begin

  CriticalSection.Enter;

  try

    Result := cdsSessions.Locate('SessionID',

      SessionID, []);

    if Result then

      Result := MinutesBetween(

        cdsSessionsLastAccess.AsDateTime, Now) < 1;

  finally

    CriticalSection.Leave;

  end;

end;

 

function TdmSessions.GetUserID(

  const SessionID: string): Integer;

begin

  CriticalSection.Enter;

  try

    Result := 0;

    if IsValidSession(SessionID) then

      Result := cdsSessionsUserID.AsInteger;

  finally

    CriticalSection.Leave;

  end;

end;

 

procedure TdmSessions.RemoveSession(

  const SessionID: string);

begin

  CriticalSection.Enter;

  try

    if IsValidSession(SessionID) then

      cdsSessions.Delete;

  finally

    CriticalSection.Leave;

  end;

end;

 

procedure TdmSessions.UpdateLastAccess(

  const SessionID: string);

begin"

A exibição deste artigo foi interrompida :(
Este post está disponível para assinantes MVP

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?