Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 04-05-2018
Avatar de Soa Pelaez
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 133
Poder: 9
Soa Pelaez Va por buen camino
Mantener Id Session DataSnap

Buen día.

Estoy manejando una aplicación cliente/servidor con la tecnología DataSnap, requiero que cuando se conecte el cliente el ID de la session se mantenga hasta que cierra completamente la aplicación, leyendo los ciclos de vida del server http://docwiki.embarcadero.com/RADSt...lass_LifeCycle establecí mi server en session y en cada invocación se me modifica el id de la session del cliente, y requiero que no se modifique el id de la session hasta que el cliente se salga.

Gracias.
Responder Con Cita
  #2  
Antiguo 07-05-2018
Avatar de Soa Pelaez
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 133
Poder: 9
Soa Pelaez Va por buen camino
DataSnap varios clientes conectados a distintas db por un mismo servicio

Buen dia



Tengo una duda, es posible conectar de forma dinamica varios clientes que acceden a distintas bases de datos por un mismo servicio en datasnap.


De antemano muchas gracias.


https://www.clubdelphi.com/foros/showthread.php?t=93037

Última edición por Casimiro Notevi fecha: 07-05-2018 a las 20:46:30. Razón: ¡!
Responder Con Cita
  #3  
Antiguo 09-05-2018
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Buen día Soa,

Bien ha hecho Casimiro en hacerte seguimiento con los hilos que has creado respecto al mismo tema, ya en uno de esos hilos te habia mostrado un enlace muy bueno que hablaba de los LifeCycles de DataSnap y creo que allí está muy claro lo que necesitas. Pero como no hemos visto código tuyo o algo que nos ayude a indicar donde está el error pues nos toca a nosotros suponer y hacer la tarea... (Lo digo de la forma mas amistosa)

Creo que tu problema es el lugar donde este ubicando tus componentes de base de datos y la clave está en el componente TServerMethods, asi:

Del lado del server:
===============
*) Create tu servidor normal.

*) Tienes un ServerMethodsUnit y Un ServerContainerUnit, el primero tiene la clase y la funcionalidad que vas a exportar y el segundo tiene los componentes de conexión y transporte (normal)

*) Verifica que en el SeverContainer tu componente DSServerClass1 tenga la propiedad LifeCycle = 'Session' (ese es el valor por defecto).

*) En algún lugar de tu programa debes tener tus componentes de BD. Para este caso, yo creo un TDataModule, y ahi ubico mi componente Connection y mi componente Query. Configuras y pruebas la conexión (Normal)

*) Volvemos al serverMehds y allí creamos una variable de tipo TDatamule que acabas de crear.

*) Defines el constructor y el destructor heredados del TServerMethods y creas dos funciones, una es para Conectar a la BD, y le vas a pasar como parámetro el ID de la BD que quieras.. tu defines como identifias tus BDs, la otra función es para probar la conexión trayendo una consulta: (Y utilizo los componentes UniDac)

Código Delphi [-]
unit ServerMethodsUnit1;

interface

uses System.SysUtils, System.Classes, Datasnap.DSServer, Datasnap.DSAuth, uDTM;

type
{$METHODINFO ON}
  TServerMethods1 = class(TComponent)
  private
    { Private declarations }
    FSoyUnID: String;
    FDtm: TDataModule1;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    Destructor Destroy; Override;
    function getID: String;
    Function ConectarBD(pBaseID: String): String;
    Function Consultar: String;
  end;
{$METHODINFO OFF}

implementation


uses System.StrUtils;

function TServerMethods1.ConectarBD(pBaseID: String): String;
begin
  Result:= 'Conectado';
  Try
    FDtm.UniConnection1.Connected:= False;
    if pBaseID.ToUpper = 'BASE1' then //Si el parametro es BASE1 conecta a TEST, o sino a QA
       FDtm.UniConnection1.Database:= 'BaseTEST'  //Aqui configuras lo que tengas que configurar para conectarte (usuario, pwd, puerto, base)
    else
       FDtm.UniConnection1.Database:= 'BaseQA';
    FDtm.UniConnection1.Connected:= True;
  Except
    On E: Exception do
       Result:= E.Message;
  End;
end;

function TServerMethods1.Consultar: String;
begin
  //pues eso.... consulta un query... las dos BDs tiene la misma estructura de tablas pero diferente data
  Try
    Fdtm.UniQuery1.Close;
    Fdtm.UniQuery1.SQL.Text:= 'Select * from prueba1';
    FDtm.Clientdataset1.Close;
    FDtm.Clientdataset1.Open;
    Result:= FDtm.ClientDataSet1.XMLData;
  Except
    On E:Exception do
       Result:= 'ERROR '+e.Message;
  End;

end;

constructor TServerMethods1.Create(AOwner: TComponent);
begin
  inherited;
  Randomize;
  FSoyUnId:= Random(10000).ToString;//esto es emulando lo del ejemplo del link que te di...
  FDtm:= TDataModule1.Create(Self); //Aqui creas tu DTM
end;

destructor TServerMethods1.Destroy;
begin
  FDtm.UniConnection1.Connected:= False;
  FDtm.Free; //Aqui destruyes el dtm
  inherited;
end;

function TServerMethods1.getID: String;
begin
  Result:= FSoyUnId; //basura...
end;

end.

En el cliente:
==========

*) Tengo un memo para escribir mensajes
*) un grid, un clientdataset (que recibe la consulta del server enviada como XML), el datasource por supuesto
*) tres botones: "getId", para traer el Id de la sesion (no es relevante), "Conectar", en donde enviamos el parametro para configurar y conectar la DB y "consultar" para traer la consulta del server (No Utilizo el DSProviderConnection paar simplificar el tema)

Código Delphi [-]
unit frmPrincipalCLI;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DBXDataSnap,
  Data.DBXCommon, IPPeerClient, Data.DB, Data.SqlExpr, ProxyDS,
  Datasnap.DBClient, Vcl.Grids, Vcl.DBGrids;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    SQLConnection1: TSQLConnection;
    Button2: TButton;
    Edit1: TEdit;
    Button3: TButton;
    DBGrid1: TDBGrid;
    ClientDataSet1: TClientDataSet;
    DataSource1: TDataSource;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    aClient: TServerMethods1Client;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}


procedure TForm2.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Add(aClient.GetID); //obtiene el Id de la session
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
 Memo1.Lines.Add( aClient.ConectarBD(Edit1.Text)); //conecta a la BD y muestra el mensaje "conectado" o un error si lo hubo
end;

procedure TForm2.Button3Click(Sender: TObject);
Var vXML: String;
begin
  vXML:= aClient.Consultar; //Trae el XML desde el server y lo asigna al CDS
  Try
    ClientDataSet1.Close;
    ClientDataSet1.XMLData:= vXML;
    ClientDataSet1.Open;
  Except
    Memo1.Lines.Add(vXML); //si hubo error muestra el xml enviado por el server
  End;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 aClient.Free; //libera el proxyDS
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  if not SQLConnection1.Connected then
     SQLConnection1.Connected:= True; //conecta el server datasap

  aClient := TServerMethods1Client.Create(SQLConnection1.DBXConnection); crea el proxyDS
end;

end.

y ya.. despues de eso obtines lo que quieres...

el punto es que el ServerMethods es el componente que se aisla y todo loq ue se defina ahi se va a comportar dependiendo de LifeCycle que definas (Servr, Session o invocación)

y cuando recuerde como subir una imagen al foro, te adjunto el resultado de mi prueba...

editado: aqui la imagen

Saludo,

Última edición por gatosoft fecha: 09-05-2018 a las 06:45:30. Razón: se agrega el link de la imagen
Responder Con Cita
  #4  
Antiguo 09-05-2018
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Como te habìa comentado en otro hilo, al no tener parte de tu codigo no podemos mas que suponer...

En el hilo que te comento, te presenté un ejemplo que hice para el problema que tenias con la conexión a BD, que es exactamente el mismo problema que debes estar teniendo con tu ID de session. No veo como te puede fallar si haces lo mismo que se hace en el artítulo de embarcadero que mencionas....

El quid, está dejar las variables en el TServerMethods... y configurar el DSServerClass como indicas LifeCycle = Session... si no te funciona, déjanos ver tu código para poderte ayudar mejor

saludo,
Responder Con Cita
  #5  
Antiguo 09-05-2018
Avatar de Soa Pelaez
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 133
Poder: 9
Soa Pelaez Va por buen camino
Gracias [gatosoft] si con el ejemplo que me habías compartido https://community.embarcadero.com/ar...hods-lifecycle logre realizar lo que necesitaba, solo quería saber si lo que estaba intentando hacer era lo viable o había otra manera, igual ese ejemplo que colocas esta bueno para alguien mas que lo necesite.

Muchas gracias.
Responder Con Cita
  #6  
Antiguo 12-05-2018
Avatar de Soa Pelaez
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 133
Poder: 9
Soa Pelaez Va por buen camino
Cita:
Empezado por gatosoft Ver Mensaje
Como te habìa comentado en otro hilo, al no tener parte de tu codigo no podemos mas que suponer...

En el hilo que te comento, te presenté un ejemplo que hice para el problema que tenias con la conexión a BD, que es exactamente el mismo problema que debes estar teniendo con tu ID de session. No veo como te puede fallar si haces lo mismo que se hace en el artítulo de embarcadero que mencionas....

El quid, está dejar las variables en el TServerMethods... y configurar el DSServerClass como indicas LifeCycle = Session... si no te funciona, déjanos ver tu código para poderte ayudar mejor

saludo,
Con lo realizado si se me conecta a las distintas db pero al momento de que cada cliente realiza una transacción y me debe retornar un numero de transacción solo retorna la del ultimo que realiza la transacción no me respeta la sessión de cada uno.
Responder Con Cita
  #7  
Antiguo 12-05-2018
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Cita:
Empezado por Soa Pelaez Ver Mensaje
Con lo realizado si se me conecta a las distintas db pero al momento de que cada cliente realiza una transacción y me debe retornar un numero de transacción solo retorna la del ultimo que realiza la transacción no me respeta la sessión de cada uno.

Habría que ver un ejemplo de lo que hablas... ¿dices que ingresas a dos bases distintas, pero al hacer una transacción ambos programas retornan la misma información? (¿te refieres a ejecutar un ExceSQL, o a un startTransacction?, o a qué?).


Necesitamos código ejemplo
Responder Con Cita
  #8  
Antiguo 15-05-2018
Avatar de Soa Pelaez
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 133
Poder: 9
Soa Pelaez Va por buen camino
Cita:
Empezado por gatosoft Ver Mensaje
Habría que ver un ejemplo de lo que hablas... ¿dices que ingresas a dos bases distintas, pero al hacer una transacción ambos programas retornan la misma información? (¿te refieres a ejecutar un ExceSQL, o a un startTransacction?, o a qué?).


Necesitamos código ejemplo
Realizó lo siguiente, luego de guardar retorno una variable con un número del registro que guardo y eso lo devuelvo al cliente, pero cuando el cliente A y el cliente B le dan guardar al mismo tiempo, uno de los
dos pierde el registro e igual no retorna el número.

Código Delphi [-]
    Conexion.StartTransaction;
    try
      iErrors := Squema.ApplyUpdates(0);
      if iErrors = 0 then
      begin
        for x := 0 to Squema.Count - 1 do
        if Squema.DataSets[x].UpdatesPending then
        begin
          Squema.DataSets[x].CommitUpdates;
          Conexion.Commit; //09/12/2015
          _ResultadoMD := 1;
        end;
      end
      else
      begin
        _ResultadoMD := 0;
        Conexion.Rollback;
      end;
    except
      on e: Exception do
      begin
        Conexion.Rollback;
       //Aqui si el número existe lo aumenta e inicia nuevamente una transacción
      end;
    end;
   //Aqui retorno el número guardado para enviarselo al cliente por medio de una función que retorna un entero.
   retNumeroDoc()
Responder Con Cita
  #9  
Antiguo 15-05-2018
Avatar de Soa Pelaez
Soa Pelaez Soa Pelaez is offline
Miembro
 
Registrado: nov 2015
Posts: 133
Poder: 9
Soa Pelaez Va por buen camino
Cita:
Empezado por Soa Pelaez Ver Mensaje
Realizó lo siguiente, luego de guardar retorno una variable con un número del registro que guardo y eso lo devuelvo al cliente, pero cuando el cliente A y el cliente B le dan guardar al mismo tiempo, uno de los
dos pierde el registro e igual no retorna el número.

Código Delphi [-]
    Conexion.StartTransaction;
    try
      iErrors := Squema.ApplyUpdates(0);
      if iErrors = 0 then
      begin
        for x := 0 to Squema.Count - 1 do
        if Squema.DataSets[x].UpdatesPending then
        begin
          Squema.DataSets[x].CommitUpdates;
          Conexion.Commit; //09/12/2015
          _ResultadoMD := 1;
        end;
      end
      else
      begin
        _ResultadoMD := 0;
        Conexion.Rollback;
      end;
    except
      on e: Exception do
      begin
        Conexion.Rollback;
       //Aqui si el número existe lo aumenta e inicia nuevamente una transacción
      end;
    end;
   //Aqui retorno el número guardado para enviarselo al cliente por medio de una función que retorna un entero.
   retNumeroDoc()
Y algo peor, me mezcla los registros que vienen del Cliente A con los del cliente B.
Responder Con Cita
  #10  
Antiguo 16-05-2018
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 21
gatosoft Va camino a la fama
Pareciera que no has solucionado tu error original. Me queda una duda:

1) A y B apuntan a bases de datos separadas (de acuerdo a un post anterior)
2) Cuando guardas A y B al mismo tiempo se pierde uno de los registros, y se mezclan los datos.

¿cuando ejecutas A y B por separado puedes verificar que los datos se guarden en BDs diferentes?

Sigo creyendo que el problema está en el lugar donde defines tus variables (Fuera del ClassMethods tal vez) por lo que puedes estar compartiendo recursos entre servidores.

¿donde defines la conexión?, en un dtm externo... está bien, pero recuerda que tu classMethods debe trabajar su propia instancia....
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Conexion a distintas db desde un mismo servicio Soa Pelaez Varios 0 24-04-2018 17:56:08
Usuarios conectados a DataSnap mjjj Providers 0 12-11-2013 20:59:24
Actualizacion de Clientes en app. multicapa con DataSnap PacoPepe Conexión con bases de datos 3 27-12-2012 19:41:52
Como Obtener un Listado de Clientes conectados a FIREBIRD???? AGAG4 Firebird e Interbase 2 24-04-2006 21:58:43
Es Posible que 2 ó más Clientes Bloqueen 1 Registro al mismo tiempo???? AGAG4 Conexión con bases de datos 0 06-01-2006 01:28:13


La franja horaria es GMT +2. Ahora son las 11:35:13.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi