Arquivo para Março, 2008

Contador de usuários on-line com a classe Application

Em alguns sistemas web pode ser interessante saber quantos usuários estão on-line, ou seja, quantos usuários estão acessando o sistema em um dado momento. A idéia é ter um contador que seja incrementado cada vez que alguém acessa o sistema e, também, seja decrementado quando um usuário sair do sistema. Para isso precisamos ter um local onde este contador possa ser armazendo e incrementado sempre que um usuário acessar nosso sistema. O problema começa na hora de decrementar quando usuário sai.

É comum que coloquemos no sistema um botão de sair para que o usuário clique e assim o sistema seja informado quando algum usuário fechar o sistema. Mas nem sempre o usuário clica neste botão. Muitas vezes o browser é fechado antes do contador ser decrementado. A insersão de um código em javascript chamando outra página que, por sua vez, faz o decremento do contador pode ser utilizada.

Minha dica é uma solução bem simples, usando o arquivo Global.asax e a classe Application. No arquivo Global.asax contém vários eventos que são disparados em momentos especias durante a execução do site. Veja alguns:

  • Application_Error: Disparado sempre que ocorre uma exceção não tratada.
  • Application_Start: Disparado quando a aplicação é iniciada. Normalmente no primeiro Request do site, ou seja na primeira vez que o sistema é chamado, após o Start ou Re-Start do servidor Web (IIS).
  • Application_End: Disparado quando o sistema web está sendo encerrado. Normalmente isso ocorre quando o servidor web está sendo interrompido por qualquer motivo.
  • Session_Start: Disparado quando uma nova sessão de usuário é iniciada.
  • Session_End: Disparado quando a sessão de usuário é encerrada.

Esses e outros eventos podem ser utilizados para vários fins.

Falando um pouco sobre a classe Application… Existe algumas maneiras de fazer com que variáveis sejam passadas de uma página pra outra. As duas abaixos são bem interessantes:

  • Variáveis de Sessão: Uma sessão é criada sempre que um navegador faz uma chamada para um servidor web, ou seja, sempre que o navegador abre um site. Váriaveis de sessão podem ser criadas e ficam disponíveis em todas as chamadas a páginas do site. A sessão só é encerrada após um tempo de inatividade entre o navegador e o servidor web. Este tempo é configurável. Essas váriaves só são vista na sessão do usuário, ou seja, uma sessão não pode ver o conteúdo de outras sessões. Sessões são criadas no lado do servidor. Essas variáveis são gerenciadas através da classe Session.
  • Variáveis de Aplicação: Uma variável de aplicação é vista pela aplicação. Isso significa que enquanto a aplicação tiver ativa a variável está dispníviel. Somente quando o servidor for reiniciado essas variáveis deixam de exisitir. E mais: variáveis de aplicação são vistas por todos usuários da aplicação. No momento que o browser chamar alguma página do site, as variáveis de aplicação estarão disponívies. A classe que gerencia essas variáveis é a classe Application.

Na nossa dica vamos usar uma variável de aplicação para ser nosso contador de usuários on-line, bem como alguns eventos do arquivo Global.asax.

No evento Application_Start do Global.asax vamos criar uma variável de aplicação. Esta variável será inicializada sempre que o servidor der algum re-start.

protected void Application_Start(object sender, EventArgs e)
{
Application.Add(“UsuariosOnLine”, Convert.ToInt32(0));
}

No Evento Session_Start vamos colocar o incrementador do contador. Todas vez que uma nova sessão for criada o contador será incrementado. Poderia deixar pra fazer este incremento após a confirmação do login/senha do usuário. Estamos facilitando as coisas. Note também que estamos colocando o timeout da sessão em 20 minutos. Sem atividade por 20 minutos a sessão expira.

protected void Session_Start(Object sender, EventArgs e)
{
lock (typeof(HttpApplication))
{
int usuariosOnline = Convert.ToInt32(Application.Get(“UsuariosOnLine”));
usuariosOnline++;
Application.Set(“UsuariosOnLine”, usuariosOnline);
}
Session.Timeout = 20;//A sessão expira em 20 minutos
}

Quando a sessão expirar o contador deverá ser decrementado.

protected void Session_End(Object sender, EventArgs e)
{
lock (typeof(HttpApplication))
{
int usuariosOnline = Convert.ToInt32(Application.Get(“UsuariosOnLine”));
usuariosOnline–;
Application.Set(“UsuariosOnLine”, usuariosOnline);
}
}

Adicionei um lock ao processo pra evitar que esse processo seja disparado ao mesmo tempo por dois ou mais usuários diferentes.

Pronto. Muito simples, não acha? Inclusive voce pode acessar a sua variável de aplicação (o contador) de qualquer lugar da sua aplicação para mosta-la em alguma página, informando quantos usuários estão on-line naquele momento. O que está mostrando na realidade são quantas sessões estão abertas.

Se quiser, baixe o arquivo abaixo e veja a implementação que fiz para um sistema que desenvolvi. ATENÇÃO: O arquivo não é um .doc e sim um .zip. Renomei após o download.

globalzip.doc

É isso aí. Qualquer dúvida é só falar. Se tiver uma proposta melhorada sobre o assunto comente aqui.

Tratamento de exceções não previstas na aplicação

Num sistema (web particularmente) agente enche a página de validators, try-catch, alerts, mensagens, máscaras de entrada, etc. tudo visando cercar as possibilidades de erro nas operações dos usuários. Mas ninguém é perfeito!!!!! Alguma coisa sempre passa e quando o usuário fizer aquilo que agente não previu vai gerar aquela página amarela de erro não tratado. Voce pode configurar uma página de erro padrão no web.config. Eu, pessoalmente, não me adaptei bem a esta solução.

Eu costumo fazer o seguinte:

  • Crio um página de erro bem amígável, tipo Erro.aspx ou Erro.htm. Inclusive a mensagem que eu coloco é esta: “Infelizmente o sistema comportou-se de maneira inesperada. A equipe de desenvolvimento foi notificada automaticamente. Esperamos solucionar o problema o mais rápido possível. Tente realizar a mesma operação mais tarde pra verificar se o problema foi corrigido. Pedimos desculpas pelos transtornos causados e contamos com a compreensão de todos.” Claro! Voce pode mudar a mensagem e arrumar bem legal na página.
  • Depois, insiro um item no website chamado Global.asax se já não tiver inserido. Este arquivo dispara vários eventos automaticamente durante a execução da aplicação. Pesquise no help do SDK sobre esse eventos mais comuns: Application_Start, Application_End, Session_Start, Session_End, Application_BeginRequest e o que nós vamos usar, Application_Error. Este evento é disparado sempre que um erro não tratado ocorrer. Se no seu Global.asax este método/evento não estiver declarado voce pode incluir como mostrado abaixo e neste evento nós iremos inserir o nosso tratamento do erro não tratado.

protected void Application_Error(Object sender, EventArgs e)
{
}

  • O código que eu insiro fará duas coisas: primeiro, gravar em um arquivo texto, tipo erros.txt, a exceção que ocorreu e de maneira cumulativa; um abaixo do outro no arquivo. Dessa forma é possível resgatar as exceções que ocorreram ao longo do uso do sistema. Os programadores podem acessar esse arquivo e corrigir os erros do sistema e depois apagá-lo, aguardando novos erros. ;) A segunda coisa é, caso este erro não tenha dado localmente, ou seja, tenha sido um erro gerado pelo usuário final, o sistema irá desviar o browser para a página de erro personalizada que criamos acima. Inclusive essa página pode ter um link para reiniciar o sistema. Se for um erro local, ou seja, na máquina do desenvolvedor, a página amarela com detalhes da exceção pode ser vista normalmente.

Esse arquivo erros.txt pode ser acessado até do url tipo http://www.meusistema.com/erros.txt. Assim o programador pode saber como o sistema anda se comportando de qualquer lugar na rede ou na internet e é dessa forma que ele fica sendo “notificado automaticamente“, como informamos na mensagem que eu coloquei na página de erro personalizado. Claro que depende do programador olhar esse aquivo sempre. Alguns podem querer que o sistema notifique por email. Questão de implementação. Eu prefiro no arquivo mesmo.

Clique aqui e baixe a implementação que fiz pra um sistema. IMPORTANTE: O arquivo não é um DOC. É um ZIP. Renomei…


Calendário

Março 2008
D S T Q Q S S
« Fev   Jun »
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Desde (04/11/07)

  • 43,583 visitas