
[RESUELTO] Pasar conexion a dll
#1
Posted 04 August 2009 - 05:23 PM
Tengo una duda... a ver si alguien sabe o puede ayudarme a checar algo...
Pregunta: Es posible pasar una conexion de DataSnap de un ejecutable a una dll como parametro?... Me tope con un documento que me dio a entender que se podia hacer esto... Pero no entendi muy bien... Alguien sabe como hacerlo?
Gracias por adelantado y saludos...
#2
Posted 04 August 2009 - 05:59 PM
DataSnap 2009 es totalmente independiente de COM y tiene herramientas mucho mas sofisticadas y poderosas que acortan la complejidad y el tiempo de desarrollo.
Si estás interesado en desarrollar algo como lo que planteas, propón un ejemplo concreto y con lo poco que se y con la colaboración de los maestros del foro miramos que podemos aportar.
Saludos
#3
Posted 04 August 2009 - 06:16 PM
Estamos desarrollando una aplicacion usando DataSnap de Delphi 2009... 3 capas... BDD Informix...
Nuestro servidor de aplicaciones tiene todo lo que son reglas de negocio... Funciona bien, normal...
Solo que tenemos un problema: Si nosotros intentamos correr una aplicacion cliente esta se conecta al servidor de aplicaciones sin problemas... Pero si intentamos correr otra pequeña aplicacion en el cliente que usa la misma conexion del servidor de aplicaciones nos manda un error que dice "Connection name in use"... El chiste es poder ejecutar las dos aplicaciones y que se conecten al mismo servidor de aplicaciones...
Y es por eso que se me ocurrio que se podia pasar la conexion para que no me marcara el error...
Procederemos entonces a investigar ese rollo del manejo de conexiones al servidor de aplicaciones...
Si alguien sabe algo se agradece cualquier colaboración o sugerencia...
Gracias por su disposicion y tiempo...
Saludos...
#4
Posted 04 August 2009 - 06:40 PM
Saludos
#5
Posted 04 August 2009 - 06:49 PM
Yo tambien creo que eso funciona... De hecho la aplicacion va a tener 4 o 5 servidores de aplicaciones corriendo al mismo tiempo en diferentes puertos... Ya lo hemos probado y funciona... (Si los puertos usados estan disponibles)...
El problema es que hay una aplicacion pequeña que todas las aplicaciones cliente van a usar y no le quieren añadir un nuevo puerto...
Realmente la solucion es la que me dices... Usar varios puertos... Pero de repente los clientes se ponen necios y de ahi no los sacas... Quieren que se use uno de los puertos ya asignados...
En fin, voy a seguir investigando un poco y si no encontramos una solucion pues usamos otro puerto... Tan facil verdad?...
De nuevo, gracias por tu tiempo y disposicion...
Saludos...
#6
Posted 05 August 2009 - 12:12 AM
https://forums.codeg...=20728&tstart=0
Saludos
#7
Posted 05 August 2009 - 06:58 AM
Saludos!
#8
Posted 05 August 2009 - 08:12 AM
axesys:
Ya habia checado ese error que me comentas... Y muy posiblemente por ahi vaya la cosa... Entiendo que en la cuarta actualizacion de delphi 2009 se arreglan varias cosas respecto a Informix... De hecho ya checamos una de ellas (Los campos TEXT de informix no los reconocia delphi 2009, y con esa actualizacion ya los reconoce)... Lo que pasa es que yo no he descargado esa actualizacion porque en la compu que desarrollo no tengo acceso a Internet... Sera cuestion de eso, de descargar y probar...
felipe:
Hacemos lo siguiente:
- En el servidor de aplicaciones tenemos una TSQLConnection a la base de datos que usa un puerto (211)...
- En una aplicacion cliente tenemos su TSQLConnection configurado con el driver de Datasnap con el puerto 211... Hasta aqui funciona bien...
- Si corremos una segunda aplicacion cliente que tiene su respectivo TSQLConnection con el driver de Datasnap y el puerto 211 es cuando marca el ya famoso "Connection name in use"...
Te refieres a esa segunda TSQLConnection en el lado cliente?... O a una segunda conexion en el servidor de aplicaciones?
A mi parecer lo mas rapido en este momento es hacer lo que dice Wilson... Otro servidor de aplicaciones para la segunda aplicacion cliente que use otro puerto... U otro TDSTCPServerTransport que use otro puerto... La cuestion es que los requerimientos dicen que tiene que ser el mismo puerto... Ya ven cosas de los clientes, que son los que pagan...
En fin, seguiremos investigando e informando...
Y de nuevo gracias por las aportaciones y el tiempo... No me canso de repetirlo...
Saludos..
#9
Posted 05 August 2009 - 08:42 AM
felipe:
Hacemos lo siguiente:
- En el servidor de aplicaciones tenemos una TSQLConnection a la base de datos que usa un puerto (211)...
- En una aplicacion cliente tenemos su TSQLConnection configurado con el driver de Datasnap con el puerto 211... Hasta aqui funciona bien...
- Si corremos una segunda aplicacion cliente que tiene su respectivo TSQLConnection con el driver de Datasnap y el puerto 211 es cuando marca el ya famoso "Connection name in use"...
Hola, de principio no habia entendido el problema, ahora me es más claro la razón de este; ahora bien, tu dices probar la solución de Wilson cambiando el puerto, pero a la vez pensando en la manera de que solo exista una compartida, en este caso desde una dll. ¿Podrías compartirnos el documento que antes viste?.
Saludos!
#10
Posted 05 August 2009 - 09:03 AM
El chiste de este asunto es realmente que dos aplicaciones cliente se ejecuten a un tiempo usando el mismo servidor de aplicaciones...
Creo que lo de la dll es como un acto desesperado por hacer que compartan el mismo servidor de aplicaciones, el mismo puerto, la misma conexion... Datasnap y Delphi deben de tener forma de hacer esto sin tanta complicacion... no creen?... Ahi va el codigo que me pasaron...
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, DB, IBCustomDataSet, IBTable, IBDatabase; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; IBDatabase1: TIBDatabase; IBTransaction1: TIBTransaction; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } user, pass, BD : string; public { Public declarations } end; const DLL_PRUEBA = 'Project2.dll'; var Form1: TForm1; PasandoComponentes : function( hWnd: THandle; IBDatabase1: TIBDatabase; IBTransaction1: TIBTransaction ) : integer; stdcall; PasandoUserPass : function( hWnd: THandle; User, Pass, BD: string ) : integer; stdcall; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var Handle: THandle; begin Handle := LoadLibrary(DLL_PRUEBA); if Handle <> 0 then begin @PasandoComponentes := GetProcAddress(Handle, 'PasandoComponentes'); try if @PasandoComponentes <> nil then begin PasandoComponentes( Self.Handle, IBDatabase1, IBTransaction1 ); end; finally FreeLibrary(Handle); end; end; // Fin del IF del Han end; procedure TForm1.Button2Click(Sender: TObject); var Handle: THandle; begin Handle := LoadLibrary(DLL_PRUEBA); if Handle <> 0 then begin @PasandoUserPass := GetProcAddress(Handle, 'PasandoUserPass'); try if @PasandoUserPass <> nil then begin BD := IBDatabase1.DatabaseName; user := 'SYSDBA'; pass := 'masterkey'; PasandoUserPass( Self.Handle, User, Pass, BD ); end; finally FreeLibrary(Handle); end; end; // Fin del IF del Han end;
Saludos...
#11
Posted 05 August 2009 - 09:26 AM
Este documento tiene algunas definiciones interesantes, tal vez se pueda conseguir algo como lo que necesitas.
Saludos!
#12
Posted 05 August 2009 - 09:45 AM
Acá dice algo de pool del datasnap 2009 y los lifecycle
http://edn.embarcade...m/article/38686
Saludos
#13
Posted 05 August 2009 - 09:52 AM
Gracias y seguimos en contacto...
Saludos...
#14
Posted 05 August 2009 - 11:51 PM
Creo saber de qué proyecto se trata.

Algo que casi siempre es clave en estos asuntos es el mensaje de error exacto que aparece en pantalla. Según nos comentas ese mensaje de error inicia con:
Esto me hace pensar que, si el servidor de aplicaciones tiene la propiedad LifeCycle en "Session" (encuentro muy recomendables las referencias dadas por Felipe y Arturo), el número de puerto no debería ser el problema."Connection name in use"
Podría ser que el origen del problema esté en algo relacionado con la propiedad ConnectionName (o incluso Name), del componente TSQLConnection de la capa cliente. Lo sé, sería muy extraño, pero hasta no descartarlo es una posibilidad.
¿Podrías hacer una prueba donde las dos aplicaciones utilicen nombres de conexiones diferentes? Podrías cambiar el valor de ConnectionName en el evento BeforeConnect de la conexión, ya que si lo intentas en tiempo de diseño te alterará otras propiedades.
También te recomiendo que hagas lo que llamo una "prueba aislada", es decir, probar con una aplicación nueva que contenga solamente los elementos necesarios para reproducir el escenario del error.
Muy buen jueves.
Al González.

#15
Posted 06 August 2009 - 11:11 AM
He probado cambiar el LifeClycle, pero el comportamiento es el mismo... Asi que creo que por ahi no es la cosa...
En unos momentos probare lo que me dices e inmediatamente informo del resultado...
Saludos...
#16
Posted 06 August 2009 - 11:37 AM
En efecto, el resultado de cambiar la propiedad ConnectionName en la conexion del lado cliente en tiempo de diseño te mueve otras propiedades...
Entonces le cambie el nombre en el evento BeforeConnect a las dos aplicaciones y el resultado fue el mismo... El mismo mensaje de error
Creo que el problema es el servidor de aplicaciones porque ahi es donde falla, es decir... El mensaje completo del error es el siguiente: "Remote error: Connection name in use"...
En fin, algo mas para descartar... Seguiremos intentando y nos leemos de nuevo...
Saludos...
#17
Posted 06 August 2009 - 12:13 PM
Pude hacer lo siguiente:
En mi servidor de aplicaciones puse una nueva conexion, configurada igual que mi conexion original... Y Pongo un dataset de ejemplo conectado a esta seguna conexion...
En el lado cliente hice una pequeña aplicacion para traer un query de ejemplo...
Acto seguido corro mi primera aplicacion y funciona bien... Ahora al correr esta nueva aplicacion FUNCIONA!... Es decir que por ahi esta el detalle... Poner otra conexion en el mismo servidor de aplicaciones para que la use la segunda aplicacion...
Ahora, la preguna es: es esto correcto?... No sera una mexicanada?...
Saludos...
#18
Posted 06 August 2009 - 01:47 PM
que bueno que te haya funcionado ese ejercicio, y es válido claro.
Aún así, si te interesa el tema del pool de conexiones, te recomiendo estos dos articulos:
http://edn.embarcade...m/article/29908
http://edn.embarcade...m/article/30027
Saludos!
#19
Posted 06 August 2009 - 03:27 PM
¿Qué pasa si con una sola conexión en el servidor de aplicaciones ejecutas dos programas cliente que se conecten a ese mismo servidor, pero desde dos máquinas diferentes? ¿Ocurre el mismo problema?
Te hago esta pregunta porque sé que esto se les presenta cuando las dos conexiones cliente vienen a crearse en el mismo proceso. ¿Pero acaso también ocurre lo mismo cuando usan una sola conexión cliente desde dos o más máquinas simultáneamente?
Y ya de paso, ¿estás haciendo estas verificaciones con código aislado en un programa de prueba o con toda la aplicación completa cargándose en memoria?
Por otra parte, podrías buscar en los fuentes de la VCL (con Find in Files) la constante que guarda el mensaje de error "Remote error" o "Connection name in use" y ver dónde y bajo qué condiciones se utiliza.
Ahora, parece ser que el mensaje de error (Remote error: Connection name in use) es compuesto. Es probable que la parte "Remote error" sea de Delphi y "Connection name in use" de Informix. Y si hablamos de que con LifeCycle en "Session" se crea una instancia de la clase servidor por cada cliente que lo necesita, podría ser que Informix no está preparado para aceptar dos conexiones de igual nombre desde la misma máquina.
Lo anterior significaría que si haces correr manualmente dos instancias de un mismo servidor de aplicaciones, que se intenten conectar ambas obviamente al servidor Informix, el segundo servidor de aplicaciones en intentarlo marcaría error, descartando finalmente que el problema sea con los enlaces cliente.
¿Cómo lo ves? :^)
Un saludo.
Al.
#20
Posted 06 August 2009 - 03:45 PM
Como lo que ya habías hecho en el BeforeConnect del TSQLConnection cliente, pero ahora con el TSQLConnection del servidor de aplicaciones.
