We help IT Professionals succeed at work.

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

155 Views
Last Modified: 2018-12-31
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

Sinisa VukSoftware architect
CERTIFIED EXPERT
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????
Software architect
CERTIFIED EXPERT
Top Expert 2012
Commented:
This problem has been solved!
(Unlock this solution with a 7-day Free Trial)
UNLOCK SOLUTION

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...

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions