How Indy IdTcpServer can transfer data of several lines to a Client?

bish wakim
bish wakim used Ask the Experts™
on
I Made a simple  "server client"  program with IdTcpServer and IdTcpClient components created with Delphi rad seattled 10.
Is there an efficient way to make the server send  a data to the client at the moment when this client is connected.  
the data should contain several lines when each line Describes each client already connected to the server  ( Id, Age name ...etc)
Thanks in Advance!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Sinisa VukSoftware architect
Top Expert 2012

Commented:
if you set event Execute of IdTCPServer.... This is taken from Indy demo project:
procedure TfrmMain.tcpServerExecute(AThread: TIdPeerThread);
var
  Client: TSimpleClient;
  Com, // System command
  Msg: string;
begin
  { Get the text sent from the client }
  Msg := AThread.Connection.ReadLn;
  { Get the clients package info }
  Client := Pointer(AThread.Data);
  { Check to see if the clients name has been assigned yet }
  if Client.Name = 'Logging In' then
  begin
    { if not, assign the name and announce the client }
    Client.Name := Msg;
    UpdateClientList;
    BroadcastMessage('System', Msg + ' has just logged in.');
    AThread.Connection.WriteLn(memEntry.Lines.Text);
  end
  else
    { If name is set, then send the message } if Msg[1] <> '@' then
    begin
      { Not a system command }
      BroadcastMessage(Client.Name, Msg);
    end
    else
    begin
      { System command }
      Com := UpperCase(Trim(Copy(Msg, 2, Pos(':', Msg) - 2)));
      Msg := UpperCase(Trim(Copy(Msg, Pos(':', Msg) + 1, Length(Msg))));
      if Com = 'CLIENTS' then
        AThread.Connection.WriteLn('@' + 'clients:' +
          lbClients.Items.CommaText);
    end;
end;

Open in new window



.. note - procedure call custom Broadcast message proc upon client connection wich iterate through
all active client connections and send some message:
procedure TfrmMain.BroadcastMessage(WhoFrom, TheMessage: string);
var
  Count: Integer;
  List: TList;
  EMote,
    Msg: string;
begin
  Msg := Trim(TheMessage);

  EMote := Trim(memEMotes.Lines.Values[Msg]);

  if WhoFrom <> 'System' then
    Msg := WhoFrom + ': ' + Msg;

  if EMote <> '' then
    Msg := Format(Trim(EMote), [WhoFrom]);

  List := tcpServer.Threads.LockList;
  try
    for Count := 0 to List.Count - 1 do
    try
      TIdPeerThread(List.Items[Count]).Connection.WriteLn(Msg);
    except
      TIdPeerThread(List.Items[Count]).Stop;
    end;
  finally
    tcpServer.Threads.UnlockList;
  end;
end;
(also part of that Indy demo project - available in Indy install folder)

Open in new window

Author

Commented:
Thank you. Iam going to test your solution very soon and come back to you.
Happy New year...

Author

Commented:
As a matter of fact  in my Indy version "AThread: TIdPeerThread"  is replaced by  "AContext: TIdContext "...
Here as my actual problem:
1. The Server (MyServer:TdTcpServer)  receives a message from client(MyClient:IdTcpClient) then returns  another message to the same
    client through the following event:
     
     procedure TFServer.MyserverExecute(AContext: TIdContext);
       var msgFromClient:string,msgToClient;
       begin
          msgFromClient := AContext.Connection.IOHandler.ReadLn;
          ......
          AContext.Connection.IOHandler.WriteLn(msgToClient));
          ......
       end;


2. the messageToClient is captured by MyClient through  TthreadComponent wich was activated inside the client application. In the client
    application   TIdTCpClient and TthreadComponent work together...
   
    procedure   ClientFormPage.IdThreadComponentRun(Sender: TIdThreadComponent)
      var msgFromServer:string;
     begin
        msgFromServer := MyClient1.IOHandler.ReadLn();
        DoSomeThing(msgFromServer);
     end;
3. the DoSomeThing((msgFromServer) causes sometimes the Program to hang!!!!!
Please how can I solve this problem????
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

Software architect
Top Expert 2012
Commented:
Because Indy is blocking at transport layer, you need to be fast as possible in client/server events. Maybe can create separate threads which will consume received strings. So, your DoSomeThing must be a thread or as fast as can be.... Be sure that you exclude sending client on server side to send notice message back - this could also be a cause of hang.

Author

Commented:
Can you give a little code showing me how can I create a thread with Delphi and perform an action with it?
The DoSomthing that caused the hang was simply when I tried to open a TabControl page wich contains indeed a lot of graphics immediatley after I received an message from the server..
I manged to get red of this problem by going around ,However I don't think it is a good idea to avoid ugly situations without understanding what is really happening.
Thanks in advance

Author

Commented:
Thank you Sinisa...

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial