Pergunta

O nosso cliente gostaria de saber que é on-line e usando atualmente o aplicativo personalizado que escreveu para eles. Eu discuti-lo com eles e isso não precisa ser exata , mais de um guestimate vai funcionar.

Então, meu pensamento é um intervalo de tempo de 15 minutos para determinar a atividade do usuário. Algumas ideias que tenho para fazer isso são as seguintes:

  1. Stamp seu registro de usuário com uma data e hora de sua última atividade cada vez que eles fazem algo que atinge o banco de dados, ou solicita uma página web ... isto embora poderia ser bastante de banco de dados intensivos.

  2. Enviar a um "quem é pedido on-line" do nosso software, procurando respostas, isso poderia ser feito em um intervalo programado, e depois carimbar o registro do usuário com a data atual e tempo para cada resposta que recebi.

Quais são seus pensamentos? E como é que você lidar com esta situação?

Clarificação

Eu gostaria de usar a mesma arquitetura para Windows ou na Web, se possível. Eu tenho uma única camada de lógica de negócios que múltiplas interfaces de usuário interagir, poderia ser o Windows ou na Web.

By Windows I significaria cliente-servidor.

Clarificação

Eu estou usando uma arquitetura n-tier para que meus objetos de negócios lidar com toda a interação com a camada de apresentação. Essa camada de apresentação poderia estar alimentando uma aplicação cliente-servidor Windows, a aplicação Web, Web Service e assim por diante.

Não é uma aplicação de alto tráfego, uma vez que foi desenvolvido para um cliente nosso, talvez 100 usuários no máximo.

Foi útil?

Solução

A nossa solução é manter uma tabela "Transação" (que segue o que foi feito), além de nossa mesa "Sessão" (que segue que estava aqui). UPDATE, INSERT e instruções DELETE são todos gerenciados através de um objeto "Transação" e cada um deles instrução SQL é armazenado na tabela "Transação" uma vez que foi executada com êxito no banco de dados (dependendo tabelas atualizadas: temos a possibilidade de especificamente siga algumas tabelas e ignorar outros). Esta tabela "Transação" tem outros campos, como transactiontType (I para INSERT, D para DELETE U para UPDATE), transactionDateTime, etc, e uma chave estrangeira "sessionId", dizendo-nos finalmente que enviaram a instrução. É ainda possível, através de um código, para identificar quem fez o quê e quando (Gus criou o registro na segunda-feira, Tim mudou o Preço Unitário na terça-feira, Liz acrescentou um desconto extra na quinta-feira, etc).

Pros para esta solução são:

  1. Você é capaz de dizer "o que quem e quando", e mostrá-lo para seus usuários! (Você vai precisar de algum código para analisar instruções SQL)
  2. Se os dados são replicados, e replicação falhar, você pode reconstruir seu banco de dados através desta tabela

Contras são

  1. 100 000 atualizações de dados por mês média de 100 000 registos em Tbl_Transaction
  2. Finalmente, esta tabela tende a ser de 99% do seu volume de banco de dados

A nossa escolha: todos os registros de mais de 90 dias são automaticamente apagadas todas as manhãs

Outras dicas

Eu vi estratégia 1 trabalho antes. É claro que o local era um pequeno.

Gostaria de saber como um site como StackOverflow faz isso?

Eles devem direcionar um evento específico, como acabei trabalhada em torno do local, dê uma olhada no meu perfil, e ainda diz algo como visto pela última vez a 8 minutos atrás .

Eu tinha acabado de soltar uma tabela de registro de log no db.

UserId int FK
Char ação (3) ( 'em' ou 'out')
Tempo DateTime

Você pode soltar um novo registro na tabela quando os logs alguém dentro ou fora ou, alternativamente, atualizar o último registro para o usuário.

Se você tiver dados da sessão é só usar isso. A maioria dos sistemas de sessão já tem data e hora para que eles possam expirar sessões não utilizadas para x minutos.

Você pode incrementar uma vez de variável global uma sessão de usuário é criado, e diminuí-lo quando ele é destruído. Desta forma, você vai sempre saber quantos usuários estão online em qualquer momento.

Se você quiser acompanhar ao longo do tempo, por outro lado, acho que o registo início de sessão e fim para o banco de dados é a melhor opção, e você calcular a atividade do usuário após o fato com uma consulta simples.

[AVISO LEGAL 1 --- solução Java]

Se cada usuário significativa é dada uma sessão, então você pode escrever sua própria implementação SessionListener para rastrear cada sessão que foi criado e destruído.

[AVISO LEGAL 2 --- código não testado ou compilado]

public class ActiveSessionsListener implements HttpSessionListener {
    public void sessionCreated(HttpSessionEvent e) {
        ServletContext ctx = e.getSession().getServletContext();
        synchronized (ctx) {
            Integer count = ctx.getAttribute("SESSION_COUNT");
            if (count == null) { count = new Integer(0); }
            ctx.setAttribute("SESSION_COUNT", new Integer(count.intValue() + 1);
        }
    }
    public void sessionDestroyed(HttpSessionEvent e) {
        ... similar for decrement ...    
    }
}

e registrar isso no seu web.xml:

<listener-class>com.acme.ActiveSessionsListener</listener-class>

Espero que isso ajude.

O único problema com uma solução de aplicação web é que muitas vezes não sabe quando alguém sinais fora. Obviamente, se você tem uma exigência de login / autenticação, você pode capturar quando uma pessoa sinais, e como parte de seu código de acesso a dados, você pode entrar quando uma pessoa atinge o banco de dados. Mas você vai ter que aceitar que haverá na maneira confiável de capturar quando uma pessoa entra fora - muitos só vai afastar-se do local, sem ter o "log off" ação

.

Eu imagino que o uso de um gatilho seria uma opção razoável que impede você de ter que mexer com quaisquer diferenças lógicas entre a web eo ambiente não-web (ou qualquer outro ambiente para que o assunto). No entanto, isso só captura muda para o meio ambiente e não fazer nada quando selecione declarações são feitas. Isso, no entanto, pode ser superada se todos os seus comandos de seus aplicativos são executados através de procedimentos armazenados.

Com uma aplicação web, o conceito de "online" é um pouco nebuloso. O melhor que você pode realmente fazer é "feito um pedido nos últimos X minutos" ou talvez "autenticados nos últimos X minutos".

Escolha um conjunto de eventos (feita solicitação, atualização realizada, autenticado, ...), e registrá-los em uma tabela DB.

Log-los para uma mesa em um DB

separado

Eu tenho trabalhado com muitos sistemas que têm utilizado o primeiro método que você listou, com um pouco de planejamento cuidadoso que pode ser feito de uma forma que realmente não tem muito efeito.

Tudo depende exatamente quando / como / o que você está tentando localizar. Se você precisa controlar várias sessões vou costuma ver pessoas que usam um sistema sessão amarrado a uma conta de usuário e, em seguida, por um determinado tempo decorrido essa sessão é consiered mortos.

Se você está realmente procurando actualmente online, sua primeira opção é a melhor.

Eu apenas implementou um sistema de última visto para o meu site. Sua primeira opção é semelhante, mas eu só atualizar a cada + -5 minutos. Ele funciona para a minha situação, mas sites de maior escala pode exigir algo um pouco extra.

<?php
function updateLastSeen($user_ref, $session_id, $db) { /*Parameters: The user's primary key, the user's session id, the connection to the database*/
  $timestamp = date('Y-m-d H:i:s');
  if ($session_id !== '') {
    /*logged in*/
    $sql_check = "SELECT user_id FROM user_last_seen WHERE user_id = ?";
    $stmt_check = $db->prepare($sql_check);
    $stmt_check->bind_param('s', $user_ref);
    $result_check = $stmt_check->execute();
    $stmt_result_check = $stmt_check->get_result();
    if ($stmt_result_check->num_rows > 0) { /*If the user's last seen was previously recorded, update his record*/
      $sql = "UPDATE user_last_seen SET last_seen = ? WHERE user_id = ?"; 
    } else { /*Otherwise, insert a record for him*/
      $sql = "INSERT INTO user_last_seen (last_seen, user_id) VALUES (?,?)";
    }
    $stmt = $db->prepare($sql);
    $stmt->bind_param('ss', $timestamp, $user_ref);
    $result = $stmt->execute();
  }
}
if( !isset($_SESSION['lastSeen']) ){ /*User logs into the website or lands on the current page, create a lastSeen variable*/
  $_SESSION['lastSeen'] = time();
  updateLastSeen($user_ref, $session_id, $db);
} else {
  $last_seen_time_difference = (time() - $_SESSION['lastSeen']) / 60;
  if ($last_seen_time_difference > 5) { //if the difference between now and the lastSeen is 5 minutes or more, record his last seen.
    updateLastSeen($user_ref, $session_id, $db);   
    $_SESSION['lastSeen'] = time(); /*after updating the database, reset the lastSeen time to now.*/
  }/* else {
    //do nothing. Don't update database if lastSeen is less than 5 minutes ago. This prevents unnecessary database hits.
  }*/
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top