Ver Mensaje Individual
  #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
Reputación: 18
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