segunda-feira, 23 de junho de 2003

Exibindo a lista dos usuários logados atualmente

Salve,


neste artigo, iremos descrever o processo de criação de uma listagem dos usuários logados no site, quer sejam anônimos ou autenticados, tal como possuímos aqui no ASP4Developers, na aba "onliners" aí ao lado. Isso é interessante para manter os usuários cientes de que não estão sozinhos, possibilitando uma maior interação entre os mesmos.


Antes de mais nada, precisaremos trabalhar com o Global.asa. Se seu host não suportar seu uso, infelizmente, não há como fazer o que estamos propondo. Chovendo no molhado, o Global.asa deve estar no diretório raiz da pasta virtual, criada no IIS ou PWS. Iniciaremos com o Application_OnStart, onde iremos inicializar a variável que armazenará a lista dos usuários.

Sub Application_OnStart()
 Application("UsuariosLogados") = "<usuarios />"
End Sub

Antes que você pense: "Lá vem o Rubens com aquele papo de XML", já adianto que vai ser com XML mesmo. Não há um motivo específico para isso. Poderíamos armazenar arrays, strings separadas por vírgulas, ou mesmo um objeto Dictionary. Acho XML mais interessante, pois permite que façamos testes com estruturas simples, que podem ser facilmente migradas para outras, mais complexas, além de nos familiarizarmos com aplicações que fazem uso do XML. Como veremos adiante, isso *não* deixa o código mais complicado.


Ok, vamos agora alimentar a variável de aplicação. Toda vez que um usuário acessar a aplicação (leia-se: quando o Session_OnStart for disparado), incluiremos um elemento no documento XML. Ficaria assim:

Sub Session_OnStart
 'Impedir que outros usuários acessem este código simultaneamente
 Application.Lock
 Dim objXMLDoc, objUsuario
 'Instanciar objeto XML. Verifique se o mesmo existe no seu servidor.
 Set objXMLDoc = Server.CreateObject("MSXML2.DOMDocument.3.0")
 'Carga síncrona. Não passe para a próxima instrução sem carregar o xml inteiro.
 objXMLDoc.async = false
 'Carregue a string XML, já tomando cuidado com caracteres acentuados.
 objXMLDoc.loadXML "<?xml version=""1.0"" encoding=""ISO-8859-1""?>" & _
  Application("UsuariosLogados")
 'Criar um novo elemento
 Set objUsuario = objXMLDoc.createElement("usuario")
 'Setar os atributos "id" e "nome"
 objUsuario.setAttribute "id", Session.SessionId
 objUsuario.setAttribute "nome", "Anônimo"
 'Adicionar o novo elemento ao documento já existente
 objXMLDoc.documentElement.appendChild objUsuario
 'Atualizar variável de aplicação
 Application("UsuariosLogados") = objXMLDoc.documentElement.xml
 'Liberar recursos alocados com o objeto
 Set objXMLDoc = Nothing
 'Liberar aos demais usuários (no bom sentido, é claro!)
 Application.Unlock
End Sub

O que é muito importante percebermos no código acima, é que o componente MSXML2.DOMDocument.3.0 precisa estar instalado no servidor. Caso o seu não o possua, o mesmo pode ser obtido gratuitamente no site da Microsoft.


Muito bem! Já possuímos a variável de aplicação com a lista de usuários. Mas, onde/quando removê-lo da lista ? Em outras palavras, não quero que um determinado usuário seja listado para sempre! Como proceder ?


Isso mesmo que você pensou! Vamos usar o evento Session_OnEnd para remover o usuário da lista! Mãos à obra:

Sub Session_OnEnd()
 Application.Lock
 Dim objXMLDoc, objUsuario
 Set objXMLDoc = Server.CreateObject("MSXML2.DOMDocument.3.0")
 objXMLDoc.async = false
 objXMLDoc.loadXML "<?xml version=""1.0"" encoding=""ISO-8859-1""?>" & _
  Application("UsuariosLogados")
 'Pesquisar no documento XML por um usuário com atributo id igual ao informado.
 Set objUsuario = objXMLDoc.selectSingleNode("//usuario[@id = " & Session.SessionId & "]")
 'Se encontrar, removê-lo
 If Not objUsuario Is Nothing Then objUsuario.parentNode.removeChild objUsuario
 Application("UsuariosLogados") = objXMLDoc.documentElement.xml
 Set objXMLDoc = Nothing
 Application.Unlock
End Sub

Parabéns, estamos quase lá! Note que adicionamos um pequeno trecho para verificar existe um usuário com o id informado no documento XML. A priori, sempre deveria existir, mas o seguro morreu de velho.


Maravilha, só precisamos agora atualizar os dados do mesmo, quando ele se logar no seu site. Adapte a mesma conforme sua necessidade.

<%
If Trim(Request.Form("txtUsuario")) <> "" And Trim(Request.Form("txtSenha")) <> "" Then
 'Abrir conexão com o banco de dados.
 'Pesquisar o registro na base de dados. Cuidado com as aspas simples nos campos postados!
 'Se encontrou então
  Application.Lock
  Dim objXMLDoc, objUsuario
  Set objXMLDoc = Server.CreateObject("MSXML2.DOMDocument.3.0")
  objXMLDoc.async = false
  objXMLDoc.loadXML "<?xml version=""1.0"" encoding=""ISO-8859-1""?>" & _
   Application("UsuariosLogados")
  'Pesquisar usuário
  Set objUsuario = objXMLDoc.selectSingleNode("//usuario[@id = " & Session.SessionId & "]")
  If Not objUsuario Is Nothing Then
   'Se encontrá-lo, alterar o nome pelo que
   ' (provavelmente) existe no banco de dados.
   objUsuario.setAttribute "nome", recordset("nome_usuario")
  End If
  Application("UsuariosLogados") = objXMLDoc.documentElement.xml
  Set objXMLDoc = Nothing
  Application.Unlock
 'Senão
  Response.Redirect "erro_login.asp"
 'Fim se
 '... restante da implementação ...'
End If
%>

Desta forma, podemos fazer com que os usuários marcados inicialmente como anônimos possam ser atualizados quando o detentor da sessão autenticar-se na aplicação.


Agora, basta listar os usuários. Acerte o design da forma que melhor lhe convier:

<%
Sub ListarUsuariosSite()
 Dim objXMLDoc, objUsuario, objUsuarios
 Set objXMLDoc = Server.CreateObject("MSXML2.DOMDocument.3.0")
 objXMLDoc.async = false
 objXMLDoc.loadXML "<?xml version=""1.0"" encoding=""ISO-8859-1""?>" & _
  Application("UsuariosLogados")
 'Coleção com todos os usuários na aplicação
 Set objUsuarios = objXMLDoc.selectNodes("//usuario")
 'Para cada usuário, ...
 For Each objUsuario In objUsuarios
  '... mostrar o nome do mesmo ...
  Response.Write "<b>" & objUsuario.getAttribute("nome") & "</b>"
  ' ... e seu respectivo id.
  Response.Write ", id " & objUsuario.getAttribute("id") & "<br>"
 Next
 'Mostrar a quantidade de usuários na aplicação
 Response.Write objUsuarios.length & " usuário(s) navegando no site, neste momento."
 Set objXMLDoc = Nothing
End Sub
%>

Resumindo: neste artigo implementamos uma lista dos usuários atualmente no site, vimos um exemplo de inclusão, alteração e exclusão de elementos e atributos em um documento XML via DOM e ainda, de quebra, ganhamos um contador de usuários online :)


Note que esta implementação é simples e flexível. Você pode colocar um campo com a data e hora de login, implementar uma rotina de comunicação como o "InterCOM" do ASP4Developers, ou mesmo possibilitar que um usuário convide outro para uma sessão de chat. Estamos limitados somente à nossa imaginação.



Espero que este artigo tenha sido útil para você.



Boa sorte e até a próxima.



Esta matéria foi postada originalmente no ASP4Developers por Rubens N. Farias (site), que na época era "pós-graduado em análise de sistemas orientados a objetos, MCP, MCSD, MCAD, MCSD.NET e consultor em TI, além de idealizador do projeto ASP4Developers. Desenvolve sistemas sob medida, focados na satisfação do usuário, com qualidade e custo realista.". Hoje, vai saber...

0 comentários: