Controlando la cantidad de usuarios en una aplicación web

Supongamos que que necesitemos controlar la cantidad de usuarios que puedan estar usando nuestra aplicación web, ya sea en Java/JSP/JSF, ASP.NET, PHP y variantes. Por ejemplo, por una cuestión de licencias, no queremos que haya más de N usuarios logueados.

Propongo acá una posible solución, algo así implementé alguna vez, pero no ha sido probada exhaustivamente.

Antes, alguna discusión de otras soluciones:

- Se puede tener control de la cantidad de usuarios logueados, si incrementamos un contador en el proceso de login, decrementamos el contador en el proceso de logout, o controlamos el fin de la sesión.

Hay algunos problemas a resolver:

- Puede que no tengamos un evento de fin de sesión, como pasa en PHP

- Puede que no tengamos un evento de fin de sesión, porque estamos en una granja de servidores, y nuestra tecnología (p.ej., ASP.NET) no registra el evento de fin de sesión de una forma adecuada en ese escenario

Alguien podría sugerir que pongamos algo en el browser cliente, un código javascript (o el más “cool”, una llamada Ajax), para que cada página envíe un “ping” al servidor, diciendo “Estoy aquí, el usuario está vivo….”. Pero eso implica colocar ese código en cada página, confiar en que el cliente tenga javascript habilitado, y quizás exija que algunos planetas esten dispuestos en línea.

Entonces, ¿qué hacemos? ¿nos entregamos a la desesperación? ¿dejamos la programación y nos dedicamos a manejar gente? o peor aún ¿nos ponemos a dibujar UML? ¡¡No!! ;-)

Podemos implementar lo siguiente:

El control debe hacerse en el login de usuario. Ahí lo dejamos pasar al usuario o no, dependiendo de un cálculo de usuarios activos que hacemos. ¿Cómo?

Para conocer los usuarios activos, en memoria (si es una aplicación corriendo en un solo servidor) o en una base de datos central (en caso de estar en una granja web), grabamos, por cada actividad de usuario (pedir una página, por ejemplo), un registro donde grabamos:

- Usuario
- Workstation (como podamos, número de IP, etc…)
- Fecha/Hora del último evento

Noten que no es un registro por evento: es un registro por Usuario+Workstation, se actualiza siempre ahi la fecha/hora de último evento. No hace falta mantener la historia de los eventos. Si el usuario pepe desde workstation1 esta pidiendo algo al sistema, actualizamos el registro que le corresponde, o lo creamos si no existe. Registros viejos, de más de una hora, o un día, se pueden borrar, periódicamente (ejecutando un store, por ejemplo, 1 de cada M actualizaciones de evento).

En el caso de ASP.NET, este registro se puede hacer en un HttpModule, sin necesidad de tocar otras partes de la aplicación. Sino, un lugar potable es colocar ese código en algún control, include o parecido, que se ejecute en el render de cada página (es muy común hoy en día, tener un componente así).

En caso de desloguearse un usuario, se borra el registro correspondiente.

Supongamos que T es el tiempo de duración de una sesión, y N la cantidad máxima de licencias. Entonces, cuando un usuario se loguea, se controla que:

- Si existe un registro para su Usuario/Workstation con fecha/hora >= hora actual – T, se lo deja pasar. Seguramente, no registramos su logout (por ejemplo, se cortó la luz) y ahora quiere entrar de nuevo.

sino

- Si existen más de N registros con fecha/hora >= hora actual – T, no se lo deja pasar

Debe haber otras soluciones, pero me parece ésta interesante, relativamente sencilla, y adoptable por distintas tecnologías. Algo similar se puede adoptar para aplicaciones en el cliente (no browser, sino una aplicación de formularios, ventanas, cliente rico).

Problemas: Hay que evaluar el impacto de tener que acceder a la base, si se decide almacenar esos registros en forma centralizada.

¿Comentarios?

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com/

This entry was posted in 1390, 1391, 5954. Bookmark the permalink.

3 Responses to Controlando la cantidad de usuarios en una aplicación web

  1. Nelson says:

    Me parece que es una solución técnica a un problema comercial. Es mucho más facil solucionarlo comercialmente que inventar algo como lo planteado.

  2. Maestro, ¿porqué tiene que mantener esto en una DB, si lo puede mantener en memoria? Si está en una granja hay que buscar un mecanismo de sincronización, pero no es tan complicado…

    Las DB son caras, la memoria sigue bajando de precio! :)

  3. Gorlok says:

    Interesante, es el mecanismo que usan muchas apps libres en php. Me identifiqué con el primer mecanismo… alguna vez participé en algo parecido (el maldito “ping”), con la diferencia que en lugar de Ajax, había un frame invisible con refresh que tenía el mismo efecto.

    Nelson -> si no existieran los problemas comerciales o de negocio, no habría necesidad de soluciones técnicas. Ellos son los que definen las reglas y nos dan de comer :) Este es un requerimiento habitual en algunos escenarios.

    Martin Salias -> es correcto. Se puede hacer en memoria, pero mientras esta información esté disponible a nivel aplicación, poco importa la implementación sino la idea. Lo más natural es pensar en un servicio de autenticación y validación de licencias… y qué él determine dónde y cómo guarda la info. Luego se ve la redundancia, etc.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>