Introdução

 

Na primeira parte deste artigo, foi mostrado como podemos detectar a inatividade do usuário de uma aplicação ASP.NET através do evento Session_End. Como explicado, o evento Session_End ocorre somente quando o tempo de inatividade especificado é atingido. Ou seja, quando o usuário acessa um outro site ou fecha o browser, o evento Session_End não é disparado automaticamente. Isso acontece porque os eventos de troca de site e de fechamento de browser ocorrem no lado cliente da aplicação, enquanto que o evento Session_End é um evento que ocorre no lado servidor. Outra limitação do evento Session_End é que ele só é chamado quando o modo do estado de sessão estiver configurado como InProc. Ou seja, quando utilizarmos algum servidor de estado para armazenar a sessão, o evento não será disparado. Caso desejemos fazer algum processamento no exato momento em que o usuário acessa outro site ou fecha o browser, precisamos desenvolver alguma funcionalidade que “avise” o servidor que algum desses eventos ocorreu. Nesta parte do artigo, explicarei algumas técnicas para que a aplicação possa notificar a ocorrência desses eventos ao servidor.

 

 

Evento onunload

 

Quando trocamos o site que estamos visitando ou fechamos a janela do browser, o evento javascript onunload é disparado no lado cliente. Portanto, esse é o local ideal para colocarmos o código de tratamento específico para quando o usuário deixar a aplicação. O que se costuma fazer neste evento é chamar uma página que seja responsável pelo encerramento da sessão do usuário. Isso pode ser feito de algumas maneiras. A forma mais comum era utilizar código javascript para abrir uma popup, apontando para a página responsável pela finalização da sessão. Com a crescente popularização dos bloqueadores de popups, essa técnica tornou-se ineficiente, pois os bloqueadores, ao impedirem a abertura da popup, impossibilitam que a página no servidor seja chamada. No exemplo deste artigo, será utilizado o conceito de AJAX - Asynchronous JavaScript and XML, para fazer a chamada à página. Explicada de maneira simplificada, a técnica AJAX permite que código javascript acesse o servidor web sem a necessidade de submeter a página, como ocorreria com um Web Form tradicional. Isso permitirá que o servidor seja acessado sem a necessidade de abertura de popup.

 

No Visual Studio 2005, abra o Web Site Saida que foi criado na primeira parte deste artigo. No Solution Explorer, clique com o botão direito do mouse sobre o Web Site Saida e escolha a opção Add New Item. Na janela que é aberta, escolha o template Web Form. Dê o nome de Finaliza.aspx e escolha a linguagem Visual C#. Esta página que acabamos de criar será a responsável por expirar a sessão do usuário quando o evento onunload ocorrer. Ainda no Solution Explorer, clique com o botão direito sobre a página Finaliza.aspx e escolha a opção View Code, para que o editor de código do Visual Studio seja aberto. No evento Page_Load da página, adicione o seguinte código:

 

 

protected void Page_Load(object sender, EventArgs e)

{

    Session.Abandon();

}

 

 

No código acima, chamamos o método Abandon() do objeto Session, que é responsável por finalizar a sessão atual. Quando ele é executado, forçamos a expiração da sessão. Assim, o evento Session_End também é disparado quando o método Abandon() é executado.

 

Obs: lembre-se que se estivéssemos utilizando um modo de armazenamento de sessão diferente de InProc, o evento Session_End não seria chamado. Neste caso, teríamos que colocar o código do evento Session_End dentro do evento Page_Load da página Finaliza.aspx. Para mais informações sobre as formas de armazenamento de sessão do ASP.NET, consulte as Referências ao final do artigo.

 

Agora, no evento onunload do browser, precisamos programar a chamada à página Finaliza.aspx. No Solution Explorer, clique com o botão direito do mouse sobre a página Pagina1.aspx e escolha a opção View Markup. Isso nos levará ao conteúdo HTML da página. Na tag <body>, adicione o atributo onunload com a chamada para a função javascript que será executada quando este evento ocorrer. A tag deverá ficar parecida com o seguinte trecho:

 

 

<body onunload="finaliza();">

 

 

Dentro das tags <head></head>, declare a função javascript finaliza(), conforme o código abaixo. Nele, utilizamos o objeto XMLHttpRequest, que é o principal componente do AJAX e responsável pelo conexão com o servidor Web. Como existem algumas diferenças na forma em que este objeto é instanciado entre cada browser, fazemos várias tentativas até que tenhamos um objeto válido. Depois, chamamos o método open() passando como parâmetros o método de acesso à página (“GET”), a página que desejamos acessar (“Finaliza.aspx”) e um valor booleano indicando se a requisição é assíncrona. Quando passamos true neste parâmetro, a chamada é feita assincronamente. Isso significa que o processamento do script continuará, independentemente da resposta vir do servidor. Assim, o browser não bloqueia o acesso a página e o usuário continua trabalhando com ela normalmente. Se passássemos false, a chamada seria feita em modo síncrono, ou seja, o browser iria esperar a resposta do servidor web para dar continuidade a execução do script. Enquanto a resposta não viesse, o usuário não conseguiria fazer mais nada na página, dando a sensação de travamento. Por último, chamamos o método send() para que o acesso seja feito.

 

 

<script language="javascript" type="text/javascript">

function finaliza()

{

    var xmlHttp=false;

 

    try {

      xmlHttp = new XMLHttpRequest();

    } catch (e1) {

      try {

        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

      } catch (e2) {

          xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

      }

    }

   

    xmlHttp.open("GET", "Finaliza.aspx", true);

    xmlHttp.send(null);

}   

</script>   

 

 

 

No Solution Explorer, clique com o botão direito do mouse sobre a página Pagina1.aspx e escolha a opção View in Browser. Para testar o funcionamento do que acabamos de fazer, acesse um outro site ou então feche o browser. Após uma dessas ações, vá ao Control Panel do Windows ® Administrative Tools ® Event Viewer. Selecione o log Application e veja o log que foi gerado por nossa aplicação. Isso mostra que quando o evento onunload foi disparado por alguma ação do lado cliente, a função javascript finaliza() chamou a página que desenvolvemos para forçar a expiração da sessão, o que por sua vez gerou a chamada ao evento Session_End, que gravou a informação de sessão expirada no log de evento do Windows.

 

Conclusão

 

Na segunda parte do artigo vimos como é possível acionar uma página no servidor web a partir de eventos ocorridos no cliente (browser). Assim, podemos detectar quando o usuário acessa um outro site ou então quando fecha o browser. Também solucionamos o problema causado pela limitação do Session_End só ser chamado quando utilizamos o modo de armazenamento InProc. Entretanto, ainda temos um problema nessa solução. Do jeito que foi implementada, sempre que outra página for acessada, a página Finaliza.aspx será chamada. O evento onunload não faz distinção entre páginas da mesma aplicação ou páginas de outros sites. Esse evento sempre é chamado em resposta à saída da página atual. Isso é um problema, já que uma aplicação web normalmente é composta de várias páginas. Assim, ao acessarmos uma outra página de nossa aplicação, a sessão acabará sendo finalizada, o que não é o comportamento correto. Na próxima parte deste artigo, explicarei como podemos contornar este problema e somente finalizar a sessão quando a aplicação for abandonada, e não a página.

 

 

Referências

 

Código fonte do exemplo deste artigo

http://www.aspneti.com/artigos/ExemploDetectarSaida.zip

 

Gerenciamento de Estado no Servidor – Parte 1 http://www.msdnbrasil.com.br/sharepedia/visualizarartigo.aspx?id=57763

 

Gerenciamento de Estado no Servidor – Parte 2

http://www.msdnbrasil.com.br/sharepedia/visualizarartigo.aspx?id=57906

 

 

Dynamic HTML and XML: The XMLHttpRequest Object

http://developer.apple.com/internet/webcontent/xmlhttpreq.html

 

 

 

Sobre o Autor

 


Ricardo Oneda Pereira de Toledo é formado em Processamento de Dados pela Faculdade de Tecnologia de São Paulo, é MCADMicrosoft Certified Application Developer, com ênfase em aplicações Web com C# e Banco de Dados SQL Server 2000 e é MVP – Most Valuable Professional em ASP/ASP.NET. Atualmente trabalha como Analista de Sistemas no desenvolvimento de aplicações Web. Visite o blog em http://oneda.mvps.org/blog