Basicamente, essas coisas funcionam da seguinte maneira.
Toda vez que o usuário realiza ações (atualização de chat, mensagem enviada, página visitada, etc) um token associado ao usuário (token que é salvo em seu servidor, DB por exemplo) é atualizado com a hora atual.
| User ID | Last action |
-------------------------------------
| 14 (mark) | 2012-02-09-10:34:53 |
| 56 (phil) | 2012-02-09-09:12:34 |
| 9 (john) | 2012-02-09-10:33:11 |
E então você decide que um usuário está online se o token dele não for muito antigo (5/10 minutos?)
Você pode melhorar esse método se usar AJAX para enviar uma solicitação periódica ao servidor a cada 1 minuto ou mais. Esta solicitação AJAX atualiza o valor do token. Dessa forma, você também pode dizer que o usuário está online se ele não fizer nada além de olhar para a página. E quando ele sai (fechar navegador ou guia), a chamada periódica AJAX para de funcionar, então após 5/10 minutos o usuário é declarado offline .
Boa sorte!