Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Internet
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-01-2006
Avatar de NickName
NickName NickName is offline
Miembro
 
Registrado: may 2003
Ubicación: Guerrero, México
Posts: 96
Poder: 22
NickName Va por buen camino
Question Mensaje de cliente a Servidor

Hola.

Despues de buscar varios dias en el foro y no encontrar algo que se paresca a mi problema que tengo me decidi por hacer esta pregunta.

Bueno primero uso Delphi7 y las Indy 9, y me encuentro desarrollando un sistemita para un cyber, Tengo una AplicacionCliente con un TIdTCPClient y tambien una AplicacionServidor con un TIdTCPServer y un TIdThreadMgrDefault.

Código:
 //--- Mi bloc de comunicaciones lo uso en ambas partes (AppServer+AppCliente)
  TComunicacion = record
                 Comando,
                 NombreUsuario,                // Quien manda el mensaje
                 Msg,                          // El Mensaje
                 NombreReceptor: string[100];  // Nombre del Receptor
                 Pc            : Integer;      // Numero de la Pc que envia
               end;
Todo funciona bien puedo mandar informacion desde mi cliente hasta el servidor y del servidor al cliente tambien:
Del cliente al servidor lo hago asi:
Código:
procedure TFrm_Principal.Button1Click(Sender: TObject);
Var
commBlock :TComunicacion;
begin
         //-- Asignar datos del bloc de comunicación
         CommBlock.Comando      := 'MENSAJE';
         CommBlock.NombreUsuario   := Client.LocalName;
         CommBlock.Msg             := 'Hola esto es una prueba :))))';
         CommBlock.NombreReceptor  := 'SERVIDOR';
         CommBlock.Pc              :=Num_Pc;
              // ---- Mandarlo ----
         
Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);

end;
Del servidor hacia el cliente hago algo parecido, mi problema es en el procedimiento Execute del Servidor al leer un mensaje del cliente si lo muestro en un Memo en el formulario principal no hay ningun problema pero lo que yo quiero es mostrar el mensaje que el cliente manda en un formulario distinto al principal, cuando muestro el mensaje el servidor se queda colgado y creo que tengo mi cerebro bloqueado ya que no encuentro la forma de mostrar el mensaje en otro formulario sin que mi servidor se cuelgue.... si alguien me puede iluminar un poco se lo agradeceria mucho... les pongo el codigo del procedimiento:
Código:
procedure TFrm_Principal.ServerExecute(AThread: TIdPeerThread);
var
  RecClient: PCliente;
  CommBlock, NewCommBlock: TComunicacion;
  RecThread: TIdPeerThread;
  i: Integer;
begin
  If Not AThread.Terminated And AThread.Connection.Connected Then
    Begin
        AThread.Connection.ReadBuffer (CommBlock, SizeOf (CommBlock));
        If (CommBlock.Comando = 'MENSAJE') Or (CommBlock.Comando = 'COMANDO') Then
          Begin
                 // es el mismo código para ambas órdenes
               If CommBlock.NombreReceptor = '' Then
                 Begin  // ningún destinatario dado se envia a todos los usuarios
                      NewCommBlock := CommBlock;  // No cambiar nada  ;-))
                      With Clientes.LockList Do
                         Try
                            For i := 0 To Count-1 Do  // interactuar con la lista de clientes
                            Begin
                                 RecClient := Items[i];           //Obtener el objeto cliente                                 RecThread := RecClient.Thread;     // Obtener el hilo del cliente
                                 RecThread.Connection.WriteBuffer(NewCommBlock, SizeOf(NewCommBlock), True);  // Enviar el paquete
                            End;
                         Finally
                         Clientes.UnlockList;
                      End;
                 End
               Else
                 Begin  //  receptor dado - busquelo y se le envía a él
                     If CommBlock.NombreReceptor = 'SERVIDOR' Then
                       Begin  // destinatario el servidor
                         Paquete:=CommBlock;
                         MostrarMensaje(Paquete); // aqui esta el problema
                       End
                     Else
                       Begin
                           NewCommBlock := CommBlock; // De nuevo no cambiar nada ;-))
                           With Clientes.LockList Do
                               Try
                                  For i := 0 To Count-1 Do
                                  Begin
                                       RecClient:=Items[i];
                                       // No tenemos ninguna función de inicio de sesion por eso usamos el DNS
                                       If RecClient.DNS=CommBlock.NombreReceptor Then
                                          Begin
                                               RecThread:=RecClient.Thread;
                                               RecThread.Connection.WriteBuffer(NewCommBlock, SizeOf(NewCommBlock), True);
                                          End;
                                  End;
                               Finally
                               Clientes.UnlockList;
                           End;
                       End;
                 End;
          End
        Else
          Begin  // Comando desconocido
               NewCommBlock.Comando := 'MENSAJE';       // El mensaje que debe mostrarse en la pantalla del cliente
               NewCommBlock.NombreUsuario := 'ADMINISTRADOR';  // El nombre del servidor
               NewCommBlock.Msg := 'Comando desconocido: "'+CommBlock.Comando+'"';  
               NewCommBlock.NombreReceptor := '[De vuelta al remitente]'; // innecesario
               AThread.Connection.WriteBuffer (NewCommBlock, SizeOf (NewCommBlock), true);  // y aqui va...
          End;
    End;
end;
el procedimiento que se ejecuta para mostrar la ventana del mensaje:

Código:
Procedure TFrm_Principal.MostrarMensaje(Pak : TComunicacion);
Begin
     Frm_Mensaje.Label1.Caption:= Pak.NombreUsuario;
     Frm_Mensaje.cxMemo1.Lines.Add('Mensaje: ' + Pak.Msg);
     Frm_Mensaje.ShowModal;
End;
__________________
Saludos...
Responder Con Cita
  #2  
Antiguo 10-01-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Yo creo que el problema está en mostrar el formulario en donde se mostrará a su vez el mensaje de forma "modal". Es decir, ¿probaste mostrando el formulario con el método "Show", y, si quieres que permanezca por encima, cambiando su propiedad "FormStyle" a "fsStayOnTop"? En cualquier caso gracias por tu mensaje, pues contiene información que me parece interesante. A ver si es posible solucionar el problema.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita
  #3  
Antiguo 10-01-2006
Avatar de NickName
NickName NickName is offline
Miembro
 
Registrado: may 2003
Ubicación: Guerrero, México
Posts: 96
Poder: 22
NickName Va por buen camino
Responder a tema

Hola.

Gracias por responder, ya probe con el metodo Show del Formulario pero cuando hago eso ni siquiera se muestra bien el formulario nadamas se pueden ver los Bordes y el mensaje con el boton no se pueden ver, y el servidor de todas formas se Bloquea.

Por otra parte con el metodo ShowModal se muestra bien el formulario del mensaje pero al darle click en el boton de Aceptar se cierra el formulario del mensaje y el servidor se Bloquea hasta que cierro el cliente que me mando el mensaje., Si yo ignoro el formulario del mensaje y doy click en cualquier parte del formulario principal puedo seguir trabajando en el servidor pero el formulario sigue visible si la propiedad FormStyle = fsStayOnTop, si esta propiedad la cambio a Normal el formulario desaparece, pero si mando otro mensaje del cliente ya no me muestra el formulario del mensaje en el servidor y este sigue Bloqueado...

Despues de cerrar el cliente que envia el mensaje puedo cerrar el servidor y me manda este mensaje:
Error de sistema. codigo 1400
El identificador de la ventana no es valido

Esto sucede con el metodo ShowModal.

Alguna otra idea
__________________
Saludos...
Responder Con Cita
  #4  
Antiguo 11-01-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 28
jachguate Va por buen camino
No olvides que los servidores indy son multihilos, por lo que al ejecutarse el evento ServerExecute, esto se realiza en el hilo de la conexión con el cliente y todas las operaciones a realizar con la VCL en la interfaz de usuario debén llevarse a cabo en el hilo principal de la aplicación, para lo que podes valerte del método Synchronize.

Saludos.
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #5  
Antiguo 11-01-2006
Avatar de NickName
NickName NickName is offline
Miembro
 
Registrado: may 2003
Ubicación: Guerrero, México
Posts: 96
Poder: 22
NickName Va por buen camino
Thumbs up Si se puede hacer

Hola.

Pues en vista de que no hay creo yo casos similares, le segui buscando y di con la respuesta y era algo sencillo, pero a falta de conocimiento entra la desesperacion.

Bueno ahora si puedo ver los mensajes sin ningun problema en el servidor con el metodo Show o ShowModal de mi formulario.

Pongo el codigo que cambio del primer mensaje que puse:
Código Delphi [-]
                     If CommBlock.NombreReceptor = 'SERVIDOR' Then
                       Begin  // destinatario el servidor
                         Paquete:=CommBlock;
                         AThread.Synchronize(MostrarMensaje); esto es lo que cambio
                       End

al procedimiento de mostrarmensaje solo le quite el parametro:
Código Delphi [-]
Procedure TFrm_Principal.MostrarMensaje;
Begin
     Frm_Mensaje.Label1.Caption:= Paquete.NombreUsuario;
     Frm_Mensaje.cxMemo1.Lines.Add('Mensaje: ' + Paquete.Msg);
     Frm_Mensaje.ShowModal;
End;

Y tube que usar AThread.Synchronize ya lo habia intentado pero el procedimiento de MandarMensaje tenia parametro y asi no se puede mandaba este error:
[Error] Principal.pas(426): There is no overloaded version of 'Synchronize' that can be called with these arguments
lo quite y jejeje Papitas...
__________________
Saludos...
Responder Con Cita
  #6  
Antiguo 11-01-2006
Avatar de NickName
NickName NickName is offline
Miembro
 
Registrado: may 2003
Ubicación: Guerrero, México
Posts: 96
Poder: 22
NickName Va por buen camino
Thumbs up Responder a tema

Hola.

jachguate
Cita:
para lo que podes valerte del método Synchronize
Tienes razon jachguate, muchas gracias cuando lei tu mensaje ya habia escrito la respuesta pero de todas formas muchas gracias ya que con tu mensaje ibamos a dar creo yo al mismo resultado
__________________
Saludos...
Responder Con Cita
Respuesta



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
licencias mysql y firebird elpinjum MySQL 8 13-08-2005 02:52:14
Mandar de Servidor a Cliente INDY TCP m@kio Internet 3 01-08-2005 16:14:35
Conectar cliente y servidor, En cualquier lugar del mundo. JXJ Internet 2 09-05-2005 17:38:21
Captura de la IP del cliente en el servidor de aplicacion (3 capas) loleras Providers 0 02-09-2004 12:50:09
Conexion interbase Servidor Linux Cliente Windows rogeriobeltran Firebird e Interbase 4 18-12-2003 00:36:44


La franja horaria es GMT +2. Ahora son las 03:54:15.


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