Introdução
Às vezes nos deparamos com a necessidade de realizar algum processamento ou executar algum código quando o usuário deixa uma aplicação web. O que, aparentemente, é uma tarefa simples, pode acabar não funcionando da maneira esperada. Por isso é importante entendermos como realmente funciona o processo. Primeiro, vamos definir o que a expressão “sair de uma aplicação ASP.NET” significa. Esta expressão pode ser aplicada quando:
- o usuário deixa de utilizar a aplicação por um determinado período de tempo
- o usuário acessa um outro site, deixando o site da nossa aplicação
- o usuário fecha o browser
Esta série de artigos mostrará como podemos detectar a ocorrência das situações descritas acima. Para isso, os exemplos dos artigos utilizarão o Microsoft Visual Studio 2005, mas você pode utilizar também o Microsoft Web Developer Express, que é uma ferramenta gratuita de desenvolvimento de aplicações web baseadas no .NET Framework 2.0, ideal para o aprendizado.
Session
A situação mais simples para ser detectada é a inatividade de um usuário por um determinado período de tempo. Para isso, precisamos entender o conceito de Session (Sessão). Uma aplicação web desenvolvida em ASP.NET cria uma sessão para cada usuário no momento em que ele faz a primeira requisição à aplicação. Cada sessão de cada usuário é identificada através de um SessionID único enviado ao browser através de um cookie não-persistente ou na URL, dependendo de como sua aplicação estiver configurada. O SessionID garante que na próxima requisição, o servidor poderá identificar de qual usuário ela partiu, dando consistência à aplicação.
O objeto Session possui o evento Session_End que é chamado sempre que a sessão de um determinado usuário expira. A sessão expira quando o usuário permanece inativo, ou seja, não gera nenhuma requisição à aplicação, por um número de minutos especificado no arquivo de configuração do web.config. Assim, o código que colocarmos no evento Session_End será executado sempre que o usuário atingir o tempo de inatividade configurado. Para mais informações sobre o objeto Session, sugiro a leitura do artigo Gerenciamento de Estado no Servidor, cujo link encontra-se na seção Referências ao final do artigo.
Vamos ver como funciona esse processo na prática. Abra o Visual Studio 2005, vá ao menu File ® New Web Site. A janela New Web Site será apresentada. Escolha o template ASP.NET Web Site e em Language escolha Visual C#. O nome do Web Site será Saída. No campo Location, podemos escolher se utilizaremos o servidor web nativo do Visual Studio 2005 ou se utilizaremos o servidor web IIS do Windows. Mantenha a opção File System selecionada para que o Visual Studio utilize o seu próprio servidor web. Escolha o diretório de sua preferência e clique em OK.
Exiba o Solution Explorer, através do menu View ® Solution Explorer, ou pelo atalho Ctrl + Alt + L, e renomeie a página Default.aspx para Pagina1.aspx. No modo Design da página, adicione um controle Button, com as seguintes propriedades:
Controle |
ID |
Text |
Label |
lblDataHora |
- |
Button |
btnPostBack |
PostBack |
Dê um duplo clique em alguma área da página Pagina1.aspx para que o editor de código seja aberto no evento Page_Load. Nele, adicione o seguinte código:
protected void Page_Load(object sender, EventArgs e)
{
lblDataHora.Text = DateTime.Now.ToString();
}
Quando a página for carregada, o código acima exibirá a data e hora atuais no Label. Essa informação será utilizada posteriormente para verificarmos a inatividade da sessão. O botão foi colocado para que seja possível simular o PostBack. A cada clique no botão, a página será recarregada e, conseqüentemente, o horário será atualizado.
Agora vamos adicionar o arquivo de configuração web.config na aplicação. No Solution Explorer, clique com o botão direito sobre o Web Site Saida e escolha a opção Add New Item. Na janela que aparece, escolha o template Web Configuration File e mantenha o nome de Web.config, conforme a figura, clicando em seguida no botão Add:
No arquivo Web.config definiremos qual o tempo de inatividade que cada sessão terá. Por padrão, este tempo é de 20 minutos, mas no nosso exemplo, iremos trabalhar com o tempo de 2 minutos. Para isso, devemos configurar o atributo timeout do elemento <sessionState>. Adicione o seguinte trecho de código no arquivo Web.config, dentro do elemento <system.web>:
<sessionState timeout="2" />
Após fazermos essa configuração, a sessão de cada usuário desta aplicação irá expirar depois de dois minutos de inatividade, ou seja, se em dois minutos não houver nenhum PostBack, a sessão expira. Se houver algum PostBack, a contagem do tempo recomeça.
Para concluir o exemplo, falta o tratamento do evento Session_End, que é disparado sempre que a sessão expira. O evento Session_End é codificado no arquivo Global.asax, que é um arquivo especial do ASP.NET que contém código relativo a eventos da aplicação e de sessão. 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 tela seguinte, escolha o template Global Application Class, selecionando a linguagem Visual C#, conforme a seguinte figura:
No evento Session_End, adicione o código abaixo:
void Session_End(object sender, EventArgs e)
{
// Code that runs when a session ends.
// Note: The Session_End event is raised only when the sessionstate mode
// is set to InProc in the Web.config file. If session mode is set to StateServer
// or SQLServer, the event is not raised.
string SourceName = "Aplicacao Saida";
if (!System.Diagnostics.EventLog.SourceExists(SourceName))
{
System.Diagnostics.EventLog.CreateEventSource(SourceName, "Application");
}
System.Diagnostics.EventLog.WriteEntry(SourceName, "Sessão expirou", System.Diagnostics.EventLogEntryType.Information);
}
No código acima, uma entrada será gravada no log de eventos do Windows quando a sessão expirar. O log de eventos do Windows é um repositório de logs no qual podemos gravar informações sobre nossa aplicação. Primeiro, definimos o nome da origem do log, ou seja, um nome que identifique a aplicação que irá gerar o log. Neste caso, demos o nome de “Aplicacao Saida”. Em seguida, verificamos se esta origem já existe. Se ela não existir, então precisaremos registrá-la através da chamada do método CreateEventSource da classe EventLog do namespace System.Diagnostics. Perceba que além do nome da origem, passamos também o nome do Log ao qual a origem estará associada. Neste caso, a fonte será utilizada no Log Application que, ao lado de Security e System, são os logs nativos do Windows. Por fim, gravamos no log a mensagem de que a sesssão expirou através do método WriteEntry.
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. Você verá uma página parecida com a figura abaixo:
Aguarde dois minutos para que a sessão expire e o evento Session_End seja executado. Para visualizarmos o conteúdo do log de eventos do Windows e confirmarmos a expiração da sessão, podemos utilizar o utilitário Event Viewer. Para acessá-lo, vá ao Control Panel do Windows ® Administrative Tools ® Event Viewer. Selecione o log Application e veja a entrada gerada pela Aplicacao Saida:
Note que foram gravados exatamente os textos que definimos no código. Neste exemplo utilizamos o log de eventos do Windows, mas nada nos impediria de fazer qualquer operação, como por exemplo, acessar um banco de dados.
Conclusão
Nesse artigo vimos como podemos detectar a inatividade da sessão do usuário de uma aplicação ASP.NET. Perceba que o evento Session_End só ocorre quando o tempo de inatividade que configuramos é atingido. Assim, quando o usuário acessa outro site ou fecha o browser, o evento Session_End não é disparado automaticamente, sendo preciso aguardar o tempo necessário para que a sessão seja considerada inativa. Assim, apesar do usuário ter saído do site em um determinado horário, a aplicação só será notificada em um momento posterior. Outra limitação é que o evento Session_End só é chamado quando o modo do estado de sessão estiver configurado como InProc. Neste modo, que é a opção padrão, as informações da sessão são armazenadas em memória no mesmo processo do ASP.NET. Além desse modo, o ASP.NET permite que as informações da sessão do usuário fiquem armazenadas em um servidor de estado que esteja rodando o serviço ASP.NET State Service ou em um banco de dados o SQL Server (para mais detalhes, consulte os links indicados na seção de Referências). Quando se utiliza uma destas duas opções, o evento Session_End não é chamado. Nas próximas partes deste artigo explicarei como podemos tratar essas situações.
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
Logging Application, Server, and Security Events
http://msdn2.microsoft.com/en-us/library/e6t4tk09.aspx
Sobre o Autor
Ricardo Oneda Pereira de Toledo é formado em Processamento de Dados pela Faculdade de Tecnologia de São Paulo, é MCAD – Microsoft Certified Application Developer, com ênfase