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 20-07-2010
Avatar de fide_uci
fide_uci fide_uci is offline
Miembro
 
Registrado: ene 2009
Ubicación: Cuba - La Habana
Posts: 226
Poder: 16
fide_uci Va por buen camino
Question Datos personalizados en los Context de la Indy

Hola amigos de clubdelphi. Quiciera comentarles que me encuentro desarrollando un juego en flash y dado que es multiplayer he tenido que tomar a delphi + indy como las opciones para crear un servidor para la aplicacion.

Todo funciona bien. Pero el problema es que por cada conexion que se crea, tengo que tener una cantidad de datos que me hacen falta y todo ello lo guardo en un puntero a un objeto que me dan los context de la Indy. O sea asi de esta manera.

Código Delphi [-]
(****************************************************************
  Declaracion del tipo TCliente para agregar otros datos a los
  Context de la Indy.
****************************************************************)

type TClient = record
 Host         : String[255]; // Guarda el IP de cada cliente
 Hora_Login   : String[255]; // Guarda la hora en la que se logueo el cliente
 Thread       : Pointer;
end;

type PClient   = ^TClient;

(****************************************************************)


//Aqui asigno los valores a las variables.
procedure TForm1.TCPServerConnect(AContext: TIdContext);
var
  NewClient: PClient;
begin
  GetMem(NewClient, SizeOf(TClient));

  NewClient.Host        := AContext.Connection.Socket.Binding.PeerIP;
  NewClient.Hora_Login  := FormatDateTime('hh:mm:ss - dd/mm/yyyy', Now);
//  NewClient.Thread      := AContext;

  TIdContext(TCPServer.Contexts.LockList.Items[TCPServer.Contexts.LockList.Count -1]).Data := TObject(NewClient);
  TCPServer.Contexts.UnlockList;

  Memo1.Lines.Add('Alguien se ha conectado desde: ' + PClient(AContext.Data).Host );
  Memo1.Lines.Add('y en fecha/hora: ' + PClient(AContext.Data).Hora_Login );
  Memo1.Lines.Add(DupeString('-', 50));
  //FreeMem(NewClient);

end;
Esto me funciona bien, pero cuando conecto otro cliente me comienza a dar errores y se me conjela la app pincipal que tengo que tumbarla de los procesos. Alguien sabe como puedo hacer eso que quiero de la forma correcta ?. Aqui pongo toda la unit para que se entienda mas !!!

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdIntercept, IdIOHandler, IdIOHandlerStream, xmldom,
  XMLIntf, msxmldom, XMLDoc, xercesxmldom, oxmldom, IdIOHandlerSocket,
  IdIOHandlerStack, IdSSL, IdSSLOpenSSL, JvSimpleXml, JvExControls,
  JvEditorCommon, JvUnicodeEditor, JvExStdCtrls, JvRichEdit,
  JvUnicodeHLEditor, JvHLEditorPropertyForm, ImgList, ComCtrls, ExtCtrls,
  XPMan, ToolWin, Menus, XPStyleActnCtrls, ActnList, ActnMan,
  IdUserPassProvider, IdSASL, IdSASLUserPass, IdSASLDigest, JvExExtCtrls,
  JvExtComponent, JvRollOut, JvWizard, Sockets, AdvShapeButton, IdContext,
  IdCustomTCPServer, IdTCPServer;

(****************************************************************
  Declaracion del tipo TCliente para agregar otros datos a los
  Context de la Indy.
****************************************************************)

type TClient = record
 Host         : String[255]; // Guarda el IP de cada cliente
 Hora_Login   : String[255]; // Guarda la hora en la que se logueo el cliente
 Thread       : Pointer;
end;

type PClient   = ^TClient;

(****************************************************************)


type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    Panel2: TPanel;
    Panel3: TPanel;
    Memo1: TMemo;
    TCPServer: TIdTCPServer;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Timer1: TTimer;
    procedure TCPServerConnect(AContext: TIdContext);
    procedure TCPServerExecute(AContext: TIdContext);
    procedure Button1Click(Sender: TObject);
    procedure TCPServerDisconnect(AContext: TIdContext);
    procedure Button2Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Button3Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var
  Form1     :TForm1;
  //Clients  :TThreadList;


implementation

{$R *.dfm}


uses StrUtils, IdBuffer, unConfigCon, IdTask;

procedure TForm1.TCPServerConnect(AContext: TIdContext);
var
  NewClient: PClient;
begin
  GetMem(NewClient, SizeOf(TClient));

  NewClient.Host        := AContext.Connection.Socket.Binding.PeerIP;
  NewClient.Hora_Login  := FormatDateTime('hh:mm:ss - dd/mm/yyyy', Now);
//  NewClient.Thread      := AContext;

  TIdContext(TCPServer.Contexts.LockList.Items[TCPServer.Contexts.LockList.Count -1]).Data := TObject(NewClient);
  TCPServer.Contexts.UnlockList;

  Memo1.Lines.Add('Alguien se ha conectado desde: ' + PClient(AContext.Data).Host );
  Memo1.Lines.Add('y en fecha/hora: ' + PClient(AContext.Data).Hora_Login );
  Memo1.Lines.Add(DupeString('-', 50));
  //FreeMem(NewClient);

end;

procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  dato: String;
  vIP: String;
  List: TList;
  vCount: Integer;
begin

  dato := AContext.Connection.Socket.ReadLn();
  Memo1.Lines.Add(#13 + DupeString('=', 30));
  Memo1.Lines.Add('Hora_Login: ' + PClient(AContext.Data).Hora_Login );
  Memo1.Lines.Add('Enviado: ' + dato);
  //AContext.Connection.Socket.WriteLn('Algo aqui !');

  List := TCPServer.Contexts.LockList;

  try
    for vCount := 0 to List.Count -1 do
    try
      vIP := PClient(TIdContext(List.Items[vCount]).Data).Host;
      TIdContext(List.Items[vCount]).Connection.Socket.WriteLn(vIP + ': ' + dato);
    except
      //TIdContext(List.Items[Count]).Stop;
    end;
  finally
    TCPServer.Contexts.UnlockList;
  end;


end;

procedure TForm1.Button1Click(Sender: TObject);
begin

  TCPServer.Active := False;
  TCPServer.Active := True;

end;

procedure TForm1.TCPServerDisconnect(AContext: TIdContext);
begin

  AContext.Data := nil;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
  List: TList;
  Count: Integer;
  vDatos: PClient;
begin

  //Memo1.Lines.Add('Hora_Login: ' + PClient(AContext.Data).Hora_Login );
// GetMem(vDatos, SizeOf(TClient));

 List := TCPServer.Contexts.LockList;
  try
    for Count := 0 to List.Count -1 do
    try
      //TIdContext(List.Items[Count]).Connection.Socket.WriteLn('Locas');
      vDatos := PClient( TIdContext(List.Items[Count]).Data);
      Memo1.Lines.Add('Hora Login: ' + vDatos.Hora_Login);
    except
    end;
  finally
    TCPServer.Contexts.UnlockList;
  end;

end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin

  TCPServer.StopListening;
  TCPServer.Active := False;

end;

procedure TForm1.Button3Click(Sender: TObject);
var
  List: TList;
  Count: Integer;
begin

  List := TCPServer.Contexts.LockList;

  try
    for Count := 0 to List.Count -1 do
    try
      TIdContext(List.Items[Count]).Connection.Disconnect(True);
    except
      //TIdContext(List.Items[Count]).Stop;
    end;
  finally
    TCPServer.Contexts.UnlockList;
  end;

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

//  Caption := IntToStr(TCPServer.Contexts.LockList.Count);
//  TCPServer.Contexts.UnlockList;

end;

end.

Última edición por fide_uci fecha: 20-07-2010 a las 23:30:11.
Responder Con Cita
  #2  
Antiguo 23-07-2010
manuc manuc is offline
Miembro
 
Registrado: abr 2010
Posts: 165
Poder: 15
manuc Va por buen camino
Hola fide_uci,

Creo que uno de los problemas puede estar aquí:
Código Delphi [-]
procedure TForm1.TCPServerExecute(AContext: TIdContext);
var
  dato: String;
  vIP: String;
  List: TList;
  vCount: Integer;
begin

  dato := AContext.Connection.Socket.ReadLn();
  Memo1.Lines.Add(#13 + DupeString('=', 30));
  Memo1.Lines.Add('Hora_Login: ' + PClient(AContext.Data).Hora_Login );
  Memo1.Lines.Add('Enviado: ' + dato);
  //AContext.Connection.Socket.WriteLn('Algo aqui !');

Ten en cuenta que el evento onExecute se dispara cada vez que un hilo tiene actividad, y es un sistema multi-hilos, es decir, más de un hilo puede estar disparándolo al mismo tiempo.

Dentro de este tipo de métodos, no puedes hacer referencias a componentes VCL directamente, sino, que tienes que hacerlo a través de métodos compartidos y llamarlos con "Synchronize", para que cuando se acceda a la VCL, se haga de modo "ordenado".

Precisamente, cuando hay conflicto de acceso a VCL en este tipo de métodos la aplicación se congela.

Espero que te ayude.

Un saludo.
Responder Con Cita
  #3  
Antiguo 24-07-2010
Avatar de fide_uci
fide_uci fide_uci is offline
Miembro
 
Registrado: ene 2009
Ubicación: Cuba - La Habana
Posts: 226
Poder: 16
fide_uci Va por buen camino
Hmm ya voy entiendiendo. Pero bueno mi error no era debido a lo de el acceso a la VCL sino a otra cosa. Es que estaba liberando un puntero y por eso me estaba dando errores. Muchas gracias por tu ayuda !
Responder Con Cita
  #4  
Antiguo 24-07-2010
Avatar de fide_uci
fide_uci fide_uci is offline
Miembro
 
Registrado: ene 2009
Ubicación: Cuba - La Habana
Posts: 226
Poder: 16
fide_uci Va por buen camino
O sea mas concretamente el error estaba en que sin darme cuenta estaba Bloqueando 2 veces la lista en la misma linea y por eso me explotaba.

Código Delphi [-]
 TIdContext(TCPServer.Contexts.LockList.Items[TCPServer.Contexts.LockList.Count -1]).Data := TObject(NewClient);
Cuando en realidad la forma correcta seria meter el LockList es una variable de tipo TList para poder acceder a ella mas o menos de esta forma.

Código Delphi [-]
...
var
   vLista: TList;
begin
   vLista := TCPServer.Contexts.LockList;
end;
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
Cuadros de mensaje personalizados radenf API de Windows 10 27-02-2009 00:43:21
JvWizardRouteMapNodes nodos personalizados? mrnovice OOP 0 23-10-2008 19:00:29
Graficos personalizados con TeeChart bustio Gráficos 0 09-01-2006 14:41:29
Reportes en personalizados jesgami Impresión 2 15-11-2005 20:35:28
Reports personalizados por el usuario taita Impresión 2 11-10-2004 17:01:02


La franja horaria es GMT +2. Ahora son las 14:00:48.


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