Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Problema con hilos para conexion de biometricas (https://www.clubdelphi.com/foros/showthread.php?t=85501)

JULIPO 26-03-2014 15:12:40

Problema con hilos para conexion de biometricas
 
Hola estoy desarrollando una aplicacion de control de acceso y asistencia con lectoras biometricas de zksoftware, estoy utilizando delphi xe4 la base de datos es mysql y para poder conectarnos via TCP/IP con las lectoras utilizamos un SDK Zkemkeeper que entrega el fabricante de las lectoras.

el problema que tenemos es el siguiente el proceso de conexion a las lectoras no es rapido si trabajamos con pocas lectoras pues los tiempos de conexion son aceptables pero si trabajamos con mas de 4 lectoras ya se hace muy lento el proceso y la informacion en las lectoras 4,5,6..n pueden demorarse hasta 3 o 4 minutos, probamos entonces con la creacion de hilos de ejecucion la idea es que se cree un hilo con cada lectora de manera que si hay problemas con la conexion de alguna de las lectoras las otras puedan recibir la informacion de manera rapida.

vamos a ver el ejemplo
Código Delphi [-]
  tprueba = class(Tthread)
  lectora1:tczkem;
  var
   ejecutando,conectado:boolean;
   error,error1,puerto1,nolectora1,ttf,version1,I:integer;
   dirip1,valor1,valor2:string;
   version:widestring;
   descripcionordenes:Ansistring;
  protected
    procedure actualiza;
    procedure actualiza1;
    constructor create(dirip:string;nolectora,puerto:integer); overload;
  public
    procedure Execute; override;
    procedure conectada(sender:Tobject);
    procedure desconexiondelec(sender:tobject);
    procedure alarma(sender: tobject; tipoalarma, nousuario,
      verificada: integer);
    procedure estadodoor(sender: tobject; tipoevento: integer);
    procedure grabacionhuellas(sender: tobject;
      EnrollNumber, FingerIndex, ActionResult, TemplateLength: integer);
    procedure huellapasa(sender:Tobject);
    procedure grabarusuario(lectora, nousuario, administrador: integer;
      nick: string; validar1: boolean);
    procedure recepciondatos(sender: tobject; EnrollNumber, IsInValid, AttState,
      VerifyMethod, Year, Month, Day, Hour, Minute, Second: integer);
    procedure tiempo1(sender: tobject);
    procedure tiempo2(novalor,limite:integer);
    Function descError:integer;
    //rutinas para trabajo de las lectoras
    Procedure validaruser(lectora,nousuario:integer;validar1:boolean);
    Procedure Borrarusuario(NoLectora3,Nousuario1:integer);
    Procedure BorrarHuella(NoLectora2,Nousuario2,Nohuella2:integer);
    Procedure GrabarHuella(nolectora4,nousuario4,nohuella4:integer;strhuella:widestring);
    Procedure Actualizatiempo(nolectora4:integer);
    Procedure Establececom;
    Procedure escribeordenes;
    Procedure conectarlectora;
  end;

desde el programa principal hacemos lo siguiente creamos un arreglo dinamico dependiendo de de la cantidad de lectoras que esten registradas en la base de datos
y creamos un thread para cada uno de los items del arreglo.
Código Delphi [-]
Var
 iniciolec:array of tprueba;
 Begin
 procedure TForm1.FormCreate(Sender: TObject);
begin
 try
  datamod.SQLConnection1.Connected:=true;
 except
   showmessage('error de conexion a la base de datos revise parametros y ejecute nuevamente');
   application.Terminate;
 end;
 if not datamod.Lectoras.Active then
  datamod.Lectoras.Active:=True;
 if datamod.Clectoras.Active then
  datamod.Clectoras.Close
 else
  begin
   datamod.Clectoras.Filter:='conexion=''TCP'' and marca=''ZKSOFT''';
   datamod.Clectoras.Filtered:=True;
   datamod.Clectoras.Active:=True;
  end;
 if not datamod.Lectoras1.Active then
  datamod.Lectoras1.Active:=True;
 if datamod.Clectoras1.Active then
  datamod.Clectoras1.Close;
 if not datamod.Usuarios.Active then
  datamod.Usuarios.Active:=True;
 if not datamod.Huellas.Active then
  datamod.Huellas.Active:=True;
 if not datamod.Actualiza.Active then
  datamod.Actualiza.Active:=True;
 if not datamod.ordenes.Active then
  datamod.ordenes.Active:=True;
 if not datamod.eventos.Active then
  datamod.eventos.Active:=True;
 if not datamod.ceventos.Active then
  datamod.ceventos.Active:=True;
 if not datamod.eventoslec.Active then
  datamod.eventoslec.Active:=True;
 contlec:=datamod.Clectoras.RecordCount;
 SetLength(iniciolec,datamod.Clectoras.RecordCount);
 SetLength(estlec,datamod.Clectoras.RecordCount);
 SetLength(vallec,datamod.Clectoras.RecordCount);
 datamod.Clectoras.First;
 while not datamod.Clectoras.Eof do
  begin //Grabamos en la base de datos el Status de lectora desconectada
   datamod.Clectoras.Edit;
   datamod.Clectoras.FieldByName('statuscon').AsInteger:=0;
   datamod.Clectoras.FieldByName('lostcon').AsInteger:=0;
   datamod.Clectoras.Post;
   datamod.Clectoras.Next;
  end;
 varlec:=0;
 datamod.Clectoras.First;
 while not datamod.Clectoras.Eof do
  begin
    vallec[varlec]:=datamod.Clectoras.FieldByName('nolectora').AsInteger;
    iniciolec[varlec]:=tprueba.create(datamod.Clectoras.FieldByName('direccionip').AsAnsiString,vallec[varlec],4370);
    iniciolec[varlec].Priority:=tplower;
    varlec:=varlec+1;
    datamod.Clectoras.Next;
  end;
 timer1.Interval:=1000;
 timer1.Enabled:=True;
 timer2.Interval:=1000;
 timer2.Enabled:=True;
 actualizahoralec.Enabled:=True;
end;
constructor tprueba.create(dirip:string;nolectora,puerto:integer);
begin
  inherited create(True);
  dirip1:=dirip;
  nolectora1:=nolectora;
  puerto1:=puerto;
  lectora1:=tczkem.Create(nil);
  lectora1.Name := 'lectora' + Inttostr(nolectora);
  lectora1.Tag := nolectora;
  lectora1.OnDisConnected := Desconexiondelec;
  lectora1.OnConnected:= conectada;
  lectora1.OnAlarm := alarma;
  lectora1.OnDoor := estadodoor;
  lectora1.OnEnrollFinger := grabacionhuellas;
  lectora1.OnAttTransaction := recepciondatos;
  timer1:=Ttimer.Create(nil);
  timer1.Enabled:=false;
  timer1.Interval:=1000;
  timer1.Tag:=1;
  timer1.OnTimer:=tiempo1;
end;
procedure tprueba.Execute;
begin
 ejecutando:=true;
 lectora1.Connect_Net(dirip1, puerto1);
 if conectado then
  begin
   lectora1.RegEvent(nolectora1, 65535);//65535 todos los eventos}
   lectora1.RefreshData(nolectora1);
   if lectora1.IsTFTMachine(nolectora1) then
      ttf := 1
    else
      ttf := 0;
    lectora1.GetSysOption(nolectora1, '~ZKFPVersion', version);
    if version = '10' then
      version1 := 10
    else
      version1 := 9;
  end;
  ejecutando:=FalsE;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
 timer1.Enabled:=False;
 timer1.Interval:=30000;
 varlec:=0;
 while varlec''<''contlec do
  begin
   if iniciolec[varlec].Suspended then
     iniciolec[varlec].Resume
   else
    begin
     if not iniciolec[varlec].conectado then
      begin
       if not iniciolec[varlec].ejecutando then
        begin
         if not iniciolec[varlec].Timer1.Enabled then
          begin
           iniciolec[varlec].Timer1.Enabled:=True;//este timer verifica la conexion de las lectoras cada 30 segundos si no se logra la conexion
          end;
        end;
      end;
    end;
   varlec:=varlec+1;
  end;
 timer1.Enabled:=True;
end;
 End.

El problema es que cuando la lectora esta en linea el software funciona muy bien, pero si hay una lectora desconectada todo el programa incluyendo el principal se queda colgado esperando el status de la conexion de esa lectora y no se si estoy en un error pero la idea de los thread es que cada uno se comporte de manera independiente.

cual sera el problema

Casimiro Notevi 26-03-2014 15:30:02

¿No traen un código de ejemplo?

JULIPO 26-03-2014 19:56:09

si traen ejemplos
 
El problema no es que tengan ejemplos por que el proceso de conexion lo logro aun que se demore lo logro el tema que planteo en mi pregunta es cuando creo varios hilos de ejecución con la intención de que si existe una demora en cualquier hilo(cada hilo maneja la comunicacion con la lectora) por que el programa principal espera la respuesta de un hilo y detiene hasta los timers (realmente detiene todo ) hasta que la lectora le contesta, si se demora 3 minutos en contestarle pues el programa queda bloqueado los 3 minutos. no se que hago mal o no he entendido cual es la funcion de los threads. mi intencion es que funcionen como programas independientes sin que se dependa de alguno para ejecutar otro.

Casimiro Notevi 26-03-2014 20:01:10

Mi pregunta es porque me parece extrañísimo que el programa tarde varios minutos en "contestar"

JULIPO 26-03-2014 21:22:03

Te aclaro
 
cuando la lectora esta en linea el software funciona muy bien pero se puede presentar el caso de que se pierda la comunicacion ya sea por desconexion fisica o por falla en la red ahi es donde el sdk se demora en contestar que se perdio la comunicacion, si esto pasa por ejemplo en la lectora 8 esperando esta respuesta todas las otras 7 quedan bloqueadas ya que el form1 (aplicacion principal) esta esperando esta respuesta

Casimiro Notevi 26-03-2014 22:10:18

"Por desconexión física o fallo en la red".
Entonces el problema está en la red, ¿por qué no se soluciona ese problema?

JULIPO 27-03-2014 06:27:22

Es una Broma
 
Acaso las redes son infalibles, me parece que la pregunta que hago es legitima y veo que esta saboteando el tema si no entiende la pregunta con gusto la podemos explicar mejor, pero no se toma ni un momento para revisar que se le esta preguntando al foro.

como extraño a roman que al menos se tomaba la molestia de leer las preguntas.

olbeup 27-03-2014 08:38:20

Cita:

Empezado por JULIPO (Mensaje 474388)
Acaso las redes son infalibles, me parece que la pregunta que hago es legitima y veo que esta saboteando el tema si no entiende la pregunta con gusto la podemos explicar mejor, pero no se toma ni un momento para revisar que se le esta preguntando al foro.

como extraño a roman que al menos se tomaba la molestia de leer las preguntas.

Hola JULIPO,

Creo que el problema de tú hilo es que no se sincroniza y estas utilizando un TTimer para sincronizar el hilo y, eso no es así, te recomiendo que repases este http://www.clubdelphi.com/foros/show...ilos+nlsgarcia para que tengas una idea clara de como utilizar el hilo (Thread)

Cita:

Acaso las redes son infalibles
Funcionan o no funcionan, pero no hay termino medio.

Cita:

me parece que la pregunta que hago es legitima y veo que esta saboteando
El ClubDelphi, está para ayudar a los compañeros que lo necesitan y, pierden su tiempo en resolver los problemas.

Cita:

como extraño a roman que al menos se tomaba la molestia de leer las preguntas.
Quedamos otros tan buenos como el compañero roman que también se le echa de menos.

Un saludo

Casimiro Notevi 27-03-2014 09:41:26

Amigo JULIPO, si vas en coche y encuentras un puente que se ha caído al fondo del abismo, la solución no es cambiar las ruedas, el motor o los asientos del coche, sino que habrá que arreglar el puente.
Si tienes problemas de red, primero de todo, arreglas la red. Es lógico, ¿no crees?
Después, si los problemas persisten, entonces es cuando hay que ver qué tiene de mal el código de tu programa.
Pero lo primero, insisto, es asegurarte de que la red está bien y no tener duda de si los problemas serán achacables a la red o al programa.

Por cierto, además de Román hay otros 80.000 usuarios, más 19 moderadores, más mucha gente preparada para ayudarte. Si no lo han hecho es porque tu planteamiento es probable que no sea el correcto y no hayan sabido o podido responderte con la información que has dado.

Todo eso es independiente de que el código que has puesto esté bien o mal, porque como has dicho tú mismo, no se sabe si es un problema de código o de la red que no funciona correctamente :confused:

JULIPO 02-04-2014 01:10:27

Informacion importante respecto a threads
 
Encontré una pagina que tiene una información que clarifico mi problema quería compartirla con ustedes para que sea útil en el foro
http://www.slideshare.net/mayrafma/m...nera-de-delphi

Ahora para clarificar cuando se hace diseño se debe contemplar todo incluso la caída del Puente.

Casimiro Notevi 08-01-2015 18:52:05

Cita:

Empezado por RedVenom (Mensaje 487470)
Hola, quiero empezar un proyecto de un lector biométrico por lo cual me gustaría saber si me podrías proporcionar un ejemplo como lograste la conexión entre Delphi la dll de zksoftware y el lector biométrico?

Gracias

Crea un hilo nuevo y explica amplicamente lo que quieres.


La franja horaria es GMT +2. Ahora son las 20:27:45.

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