
[RESUELTO] Dos o más aplicaciones con un soló login
#1
Escrito 06 abril 2011 - 09:37
como siempre muchas gracias por vuestra ayuda.
#2
Escrito 06 abril 2011 - 10:08
Creo que lo mas sencillo, ''si se usa bd'' es que al loguearse el usuario se coloque como activo en la bd ''un campo adicional''.
Si esta activo, ya, si no, a loguearse.
Saludos
#3
Escrito 06 abril 2011 - 10:20
Edito, pensándolo mejor, seguimos con el problema de si hay una caída de sistema, se quedaría como activo. sigo pensando que sería muy buena solución salvo por este detalle, tal vez una tabla en memoria, pero como leo una tabla en memoria si esta creada desde otra aplicación, no se si habría manera???.
#4
Escrito 06 abril 2011 - 10:25
#6
Escrito 06 abril 2011 - 11:17
Amigo para eso esta el evento OnDestroy.
Si el programa se cierra abructamente se actualiza la bd.
Por otro lado con un timer se puede verificar que la conexión a la bd este activa.
Te pongo un ejemplo, asi es como lo uso yo en mi programa, mas o menos.

Saludos
Archivos adjuntos
#7
Escrito 06 abril 2011 - 11:26
Para algo como esto me inclino por crear una .DLL, en la cual haya una variable global que indique si el usuario está autentificado o no, así como otros valores que quieras que se compartan. Cualquier programa que haga uso de dicha .dll sabrá si el usuario se identificó desde una aplicación previa y no lanzará el login. La ventaja de la .dll es que se borra su información al cerrar el sistema, y puede ser programada para que se elimine de la memoria en cuanto se cierre el último programa que hace uso de ella, de esa forma no tendrías que llevar un contador de "programas clientes", directamente se borraría la información del login con el último programa que la usara.
La .dll sería muy sencilla y podría incluir ella misma el formulario de login, de manera que con única función del tipo AutentificaUsuario(Name: string) : Boolean, si dicho usuario no está autentificado que lance el login, en caso contrario que devuelva TRUE sin mostrar ningún login.
Supongo que no debe ser muy complicado de hacer.
#8
Escrito 06 abril 2011 - 11:32
El problema es que las cosas hay que compararlas con algo.
Si el sistema se cae, CREO que lo que le preocupa a Jose Luis es que se cae la bd, no la aplicación, osea que no hay comunicación con la BD.
El programa puede estar activo, sin embargo la BD no.
Ahi es donde creo que esta el asunto.
Saludos
#9
Escrito 06 abril 2011 - 12:42
En efecto, en ambos casos comparamos con un valor almacenado, pero mientras en el caso de la .DLL comparamos con un valor que reside en la memoria RAM, con la ventaja de que si cae el sistema se resetea a FALSE, si lo grabamos en la BD ese valor permanece a TRUE; en caso de que haya un corte de luz, por ejemplo, ¿cómo sabe el programa la próxima vez que arranca que no está autentificado si la BD le dice que sí?Hola
El problema es que las cosas hay que compararlas con algo.
Desde el punto de vista de la aplicación, el evento OnDestroy que comentas puede que no siempre esté en disposición de grabar nada en la BD, puesto que se supone que ha sucedido cualquier error inesperado, a partir de ahí no se garantiza que el programa sea capaz de hacer nada consistente.
Otra cosa es si, dependiendo del sistema de BBDD empleado, en su mecanismo de control de sesiones ya informa de si un usuario está o no conectado y con esa información es suficiente para no tener que preocuparse de nada más.
Puede haber varios escenarios de "cuelgue", el sistema puede caer de muchas formas y hay que estar preparado para todas. Como dices, puede ser que la BD caiga, en ese caso puede que la aplicación se quede activa pensando erroneamente que está autentificada, lo que comentabas en un mensaje anterior de utilizar un Timer puede servir para testear si se ha perdido la conexión, y ese mecanismo puede realizarse tanto desde la misma aplicación como desde la propia .DLL que sirve de nexo a todas las aplicaciones.Si el sistema se cae, CREO que lo que le preocupa a Jose Luis es que se cae la bd, no la aplicación, osea que no hay comunicación con la BD.
El programa puede estar activo, sin embargo la BD no.
Ahi es donde creo que esta el asunto.
Saludos
Esto nos llevaría a un sistema mixto, preveyendo que caigan o bien el programa o bien la BD, en en ese caso cuando algunas de las dos informaciones de FALSE, se debe volver a autentificar.
Saludos
#10
Escrito 06 abril 2011 - 02:06
Me parece correcta tu apreciación.

El problema mio es el desconocimiento del uso de DLL, casi no las he usado y cuando lo he hecho ha sido para regresar algún valor de una función sencilla.
No me imagino como se podría usar para ese control, ya esta fuera de mi poco alcance.

Saludos
#11
Escrito 07 abril 2011 - 01:01
Caral, estoy al igual que tu verde totalmente sobre DLL,

Wilson, interesante articulo, es una de las opciones que estoy barajando.
Andres1569, creo que el planteaminto en DLL que comentas sería el más correcto para lo que quiero, pero como confieso más arriva, no tengo ni idea de su uso, buscare aver si me entero de su uso y puedo aplicarlo.
Una aclaración sobre el sistema que comentaba, los programas auxiliares, no deben pedir el logo, si el programa general esta activo, pero no al revez. Lo comento por si esto afectara al diseño?.
#12
Escrito 07 abril 2011 - 04:39
Es posible leer la en el espacio de direcciones de otro proceso (1 y 2) con las APIs VirtualAllocEx y WriteProcessMemory. Sin embargo se debe ser cuidadoso y tener en cuenta que un AV puede "Saltar". No creo que sea la forma de elección.
Quizás aquí 1, 2, 3 o 4 encuentres ayuda.
Saludos.
#13
Escrito 07 abril 2011 - 11:46
Eso no es un problema, es un GRAN problema,El asunto de la DLL tiene un problema, las variables globales en una dll lo son sólo para cada aplicación que la carga, no se comparten.


He mirado esos enlaces y creo que lo del enlace 1, donde pones un ejemplo de uso de ficheros compartidos en memoria, puede ser lo más recomendable para este propósito. A ese respecto me he acordado de un ejemplo que puso Al González en su bitácora sobre una clase llamada SuperGlobal que encapsulaba en un objeto Delphi el uso de esa memoria compartida, supongo que es parecido al ejemplo en C++ de SharedMemory que pusiste.
Saludos
Saludos
#14
Escrito 07 abril 2011 - 12:13





Ahora que recuerdo, teníaaaaaa una amigo que estudio en la universidad una carrera relacionada con la informática, y recuerdo que me dijo su último año, estoy deseando terminar la carrera, para dejar de estudiar, Pobre iluso.
#15
Escrito 07 abril 2011 - 12:26
... por lo que he visto por encima también debería estudiar el tema de las DLL.
Si estudialo pero no para tratar de usar Variables globales entre aplicaciones, te aseguro que no funcionará

Saludos.
#16
Escrito 07 abril 2011 - 01:21
Siguiendo una de las propuestas de Escafandra, usando el mecanismo que ofrece Windows para manejar archivos compartidos en memoria, me he apoyado en un código que colocó Al González en su bitácora hace un tiempo, se trata de una clase llamada SuperGlobal que permite manejar un objeto desde varias aplicaciones dentro de la misma máquina, como si fuera una variable global a todo el sistema. Dicha clase almacena sus variables internas en esa memoria compartida, y facilita que se pueda usar desde varias aplicaciones que instancien dicha clase. Ignoro si puede dar algún efecto secundario esa técnica, yo lo he probado en Windows 7 y de momento funciona correctamente.
Lo único que hago es derivar de TSuperGlobalObject una clase llamada TDBLogin, que mantiene una lista de usuarios autentificados, para su consulta por parte de varias aplicaciones escritas en Delphi. Esta clase dispone de tres métodos básicos, para añadir un usuario (método LogUser), otra para quitarlo (método UnlogUser), y otra para consultar si un usuario ya está autentificado previamente (método UserIndex que devuelve un número mayor a -1 si ya estaba en la lista).
Para almacenar los usuarios se utiliza una estructura de registro, que almacena una cadena (UserName : string[64]) para el nombre de usuario y un contador (ClientCount : Integer) para memorizar el número de aplicaciones que usan dicho usuario, de esta forma cuando una aplicación da de alta un usuario se incremente el contador y cuando lo da de baja se decrementa, y sólo se elimina el usuario de la lista cuando ya no hay ninguna aplicación que lo use. Este sistema es mejorable, desde luego, y debe usarse con algunas precauciones, es decir, cada aplicación debe llamar a UnLogUser tantas veces como haya llamado a LogUser. Y por descontado, se presupone que el proceso de logueo a la BD le corresponde a la aplicación, la clase TDBLogin sólo informa de los usuarios que le indiquemos.
Hay que tener en cuenta que, como señala Al González en la explicación de su código, se prohibe el uso de punteros, por lo que la clase TDBLogin no declara listas dinámicas, ni estructuras del tipo TList, por lo que uso un array acotado a 20 para almacenar los usuarios, y las cadenas tienen una longitud fija. Se puede ampliar la clase para almacenar más información teniendo en cuenta esa limitaciones.
Ficheros adjuntos:
AGSuperGlobals.pas => Código de Al González que implementa la clase TSuperGlobalObject
DBLogin.pas => Código que implementa una sencilla clase TDBLogin, descendiente de TSuperGlobalObject, y que se encarga de almacenar los usuarios que le indiquemos.
Resto de archivos => Un programa de ejemplo, PruebaDBLogin, que muestra el uso de esa técnica. Basta con ejecutar varias instancias de dicho programa y jugar con él para ver cómo se comparte la información entre varias aplicaciones.
Saludos
Archivos adjuntos
#17
Escrito 07 abril 2011 - 03:13
Muy interesante.
Entonces el uso de .pas hace la funcion que podria hacer una dll o varias dll compartiendo recursos?.
Interesante tema.
Saludos
#18
Escrito 07 abril 2011 - 04:15
Prefiero compartir justo lo necesario y nada mas, así nada se escapará de las manos.

Saludos.
#19
Escrito 07 abril 2011 - 08:25
Yo creo que debe necesariamente identificarse.
La solución que yo propongo es una pequeña aplicación que haga las veces de recepcionista (que permanecerá siempre abierta), el usuario solo se loguea una única vez en la recepción, y las aplicaciones dependientes no se ejecutan directamente si no que las ejecuta la aplicación recepcionista. Dicha aplicación podría ser un form fsStayOnTop con tantos botones como aplicaciones necesite manejar, lo demás es carpintería.
Saludos
#20
Escrito 08 abril 2011 - 01:02

El programa que estoy haciendo en mi empresa, me parece que es demasiado grande, por eso lo divido en el programa general y varios auxiliares, claro cada uno tiene que logearse, por eso planteaba este problema. Normalmente usare yo el program,a y hare las llamadas desde el programa Principal, pero otras veces puedes necesitar usar sólo un auxiliar.
Mi siguiente duda lógica sería, que pidiese el logín si se abre desde otro punto de la red.????