Question

Notre client souhaite savoir qui est en ligne et utilise actuellement l'application personnalisée que nous avons conçue pour lui. J'en ai discuté avec eux et il n'est pas nécessaire que cela soit exact : plus d'hostimate fonctionnera.

Je pensais donc à un intervalle de temps de 15 minutes pour déterminer l'activité de l'utilisateur. Voici quelques idées pour cela:

  1. Marquez leur enregistrement utilisateur avec la date et l'heure de leur dernière activité à chaque fois qu'ils font quelque chose qui frappe la base de données ou demande une page Web ... ceci pourrait cependant être assez gourmand en base de données.

  2. Envoyez une requête "qui est en ligne" " À partir de notre logiciel, en cherchant des réponses, vous pouvez le faire à un intervalle programmé, puis apposer un tampon sur l’enregistrement de l’utilisateur avec la date et l’heure actuelles pour chaque réponse reçue.

Quelles sont vos pensées? Et comment géreriez-vous cette situation?

Clarification

Si possible, j'aimerais utiliser la même architecture pour Windows ou le Web. J'ai une seule couche de logique métier avec laquelle plusieurs interfaces utilisateur interagissent, par exemple Windows ou le Web.

Par Windows, je veux dire client-serveur.

Clarification

J'utilise une architecture à plusieurs niveaux afin que mes objets métier gèrent toutes les interactions avec la couche de présentation. Cette couche de présentation pourrait alimenter une application Windows client-serveur, une application Web, un service Web, etc.

Ce n’est pas une application à fort trafic, car elle a été développée pour un de nos clients, peut-être 100 utilisateurs au maximum.

Était-ce utile?

La solution

Notre solution consiste à gérer une "Transaction". table (qui suit ce qui a été fait), en plus de notre "Session" table (qui suit qui était ici). Les instructions UPDATE, INSERT et DELETE sont toutes gérées par un "Transaction". objet et chacune de ces instructions SQL est stockée dans le dossier "Transaction". table une fois exécutée avec succès sur la base de données (en fonction des tables mises à jour: nous avons la possibilité de suivre certaines tables et d’ignorer d’autres). Cette " Transaction " La table a d'autres champs tels que transactiontType (I pour INSERT, D pour DELETE, U pour UPDATE), transactionDateTime, etc., et une clé étrangère "sessionId", nous indiquant finalement qui a envoyé l'instruction. Il est même possible, par un code, d’identifier qui a fait quoi et quand (Gus a créé le disque lundi, Tim a changé le prix unitaire le mardi, Liz a ajouté une réduction supplémentaire le jeudi, etc.).

Les avantages de cette solution sont les suivants:

  1. vous êtes en mesure de dire "qui et quand" et de le montrer à vos utilisateurs! (vous aurez besoin de code pour analyser les instructions SQL)
  2. si vos données sont répliquées et que la réplication échoue, vous pouvez reconstruire votre base de données via cette table

Les inconvénients sont

  1. 100 000 mises à jour de données par mois signifient 100 000 enregistrements dans Tbl_Transaction
  2. Enfin, cette table représente généralement 99% du volume de votre base de données

Notre choix: tous les enregistrements de plus de 90 jours sont automatiquement supprimés chaque matin

Autres conseils

J'ai déjà vu la stratégie 1 fonctionner. Bien sûr, le site était petit.

Je me demande comment un site comme stackoverflow le fait?

Ils doivent cibler un événement spécifique, car je viens de parcourir le site, de consulter mon profil et de dire quelque chose comme vu pour la dernière fois il y a 8 minutes .

Je viens de déposer une table d'enregistrement de journal dans la base de données.

UserId int FK
Action char (3) ('in' ou 'out')
Heure DateHeure

Vous pouvez supprimer un nouvel enregistrement dans la table lorsque quelqu'un se connecte ou se connecte ou bien mettre à jour le dernier enregistrement de l'utilisateur.

Si vous avez des données de session, utilisez-les simplement. La plupart des systèmes de session ont déjà des horodatages afin qu'ils puissent expirer les sessions non utilisées pendant x minutes.

Vous pouvez incrémenter une variable globale chaque fois qu'une session utilisateur est créée et la décrémenter lorsqu'elle est détruite. Ainsi, vous aurez toujours le nombre d'utilisateurs en ligne à un moment donné.

Par contre, si vous souhaitez surveiller le processus dans le temps, je pense que la meilleure solution consiste à consigner le début et la fin de la session dans la base de données. Vous calculez ensuite l'activité de l'utilisateur à l'aide d'une simple requête.

[AVERTISSEMENT 1 --- solution Java]

Si une session est attribuée à chaque utilisateur significatif, vous pouvez écrire votre propre implémentation SessionListener pour suivre chaque session créée et détruite.

[AVERTISSEMENT 2 --- Code non testé ni compilé]

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 ...    
    }
}

Et enregistrez ceci dans votre web.xml:

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

J'espère que cela vous aidera.

Le seul problème avec une solution d'application Web est que vous ne savez souvent pas quand quelqu'un se déconnecte. Évidemment, si vous avez une exigence de connexion / d’authentification, vous pouvez capturer le moment de la connexion d’une personne et, dans le cadre de votre code d’accès aux données, vous pouvez vous connecter quand une personne accède à la base de données. Mais vous devrez accepter qu'il y aura un moyen fiable de capturer quand une personne se déconnectera - beaucoup vont simplement quitter le site sans prendre la "déconnexion" action.

J'imagine que l'utilisation d'un déclencheur serait une option raisonnable qui vous éviterait d'avoir à vous soucier des différences logiques entre l'environnement Web et l'environnement non Web (ou tout autre environnement). Cependant, cela ne capture que les modifications apportées à l'environnement et ne fait rien lorsque des instructions select sont faites. Toutefois, ceci peut être surmonté si toutes vos commandes de vos applications sont exécutées via des procédures stockées.

Avec une application Web, le concept de "en ligne". est un peu nébuleux. Le mieux que vous puissiez faire est de "faire une demande au cours des X dernières minutes". ou peut-être "authentifié au cours des X dernières minutes".

Choisissez un ensemble d'événements (demande faite, mise à jour effectuée, authentifié, ...), et connectez-les à une table de base de données.

Consignez-les dans une table d'une base de données distincte

J'ai travaillé avec de nombreux systèmes qui utilisaient la première méthode que vous avez énumérée, avec une planification minutieuse qui peut être faite d'une manière qui n'a vraiment pas beaucoup d'effet.

Tout dépend du moment, de la méthode et de ce que vous essayez de suivre. Si vous devez suivre plusieurs sessions, je verrai généralement des personnes qui utilisent un système de session lié à un compte d'utilisateur, puis à un moment donné, cette session est considérée comme morte.

Si vous recherchez réellement actuellement en ligne, votre première option est la meilleure.

Je viens de mettre en place un dernier système vu pour mon site web. Votre première option est similaire, mais je ne mets à jour que toutes les + -5 minutes. Cela fonctionne dans mon cas, mais les sites Web à grande échelle peuvent nécessiter quelque chose d'un peu plus.

<?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(

Je viens de mettre en place un dernier système vu pour mon site web. Votre première option est similaire, mais je ne mets à jour que toutes les + -5 minutes. Cela fonctionne dans mon cas, mais les sites Web à grande échelle peuvent nécessiter quelque chose d'un peu plus.

<*>SESSION['lastSeen']) ){ /*User logs into the website or lands on the current page, create a lastSeen variable*/

Je viens de mettre en place un dernier système vu pour mon site web. Votre première option est similaire, mais je ne mets à jour que toutes les + -5 minutes. Cela fonctionne dans mon cas, mais les sites Web à grande échelle peuvent nécessiter quelque chose d'un peu plus.

<*>SESSION['lastSeen'] = time(); updateLastSeen($user_ref, $session_id, $db); } else { $last_seen_time_difference = (time() -

Je viens de mettre en place un dernier système vu pour mon site web. Votre première option est similaire, mais je ne mets à jour que toutes les + -5 minutes. Cela fonctionne dans mon cas, mais les sites Web à grande échelle peuvent nécessiter quelque chose d'un peu plus.

<*>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);

Je viens de mettre en place un dernier système vu pour mon site web. Votre première option est similaire, mais je ne mets à jour que toutes les + -5 minutes. Cela fonctionne dans mon cas, mais les sites Web à grande échelle peuvent nécessiter quelque chose d'un peu plus.

<*>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. }*/ }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top