Newsgroups : Borland : borland.public.delphi.internet.winsock : 2005 Jul : unsolicited data from server with indy

www.cryer.info
Managed Newsgroup Archive

unsolicited data from server with indy

Subject:unsolicited data from server with indy
Posted by:"keyser" (keyser_so..@usa.com)
Date:27 Jul 2005 06:09:07

I asked a related question a few weeks ago.  I have created a
design that appears to work but I am not sure if I have created a
good design or a monster.

Here are the details:
I have a custom client/server application where the client(s)
will pull data as needed.  The indy client works perfect for this.
However, a single client can cause the need for data to be sent
to all other clients without their express request.  Using the
Borland's socket components, this is an easy task (although with
the disadvantages mentioned in the Indy docs.)  Since I am trying
to 'forget what I have learned' (again, from the Indy docs), I
have been trying to use just the Indy components.

In order to get Data from the Server to the Client I have these
choices:
1) Server queues data, Client polls at regular intervals.
2) Server instantiates a client socket and client instantiates a
server socket.
3) Client sends command asking for next piece of data, then
immediately reads on the socket, effectively blocking until
satisfied.  Server takes note of request and notes what
connection command was made on.  When data is available, Server
dequeues the noted connection and satisfies the read.

(there may be more but these are the 3 I thought of)

I chose the 3rd scenario as the first could have an excessive
amount of unneeded traffic, and the second has the server
as the client and client as the server.

Here is some of the code I have for this mechanism:

//Client thread loop to constantly prime the pump:

procedure TClientPollThread.Execute;
var
  count,i : integer;
  c : char;
begin
  while not Terminated do begin
    try
      if not remoteform.RemotePollClient.Connected then
          remoteform.RemotePollClient.Connect();

      remoteform.RemotePollClient.WriteLn('REQUESTDATA');
      remoteform.RemotePollClient.ReadTimeout := 10000;
      count := remoteform.RemotePollClient.ReadInteger;
      for i := 1 to count do begin
          c := char (remoteform.RemotePollClient.ReadInteger);
          processChar( c );
      end;
    except
      // may get timeout exceptions which are fine
    end;
  end;
end;

//Server command handler:

Var activePollRequests : Tlist; // created in form create

procedure TRemoteForm.RemoteTCPServerRemoteRequestDataCommand(
  ASender: TIdCommand);
begin
  try
    activePollRequests.Add(Asender.Thread);
  except
    on e: exception do begin
    debugLogmessage('Exception in '+
           'TRemoteForm.RemoteTCPServerRemoteRequestDataCommand'+
           ^M^J+e.Message);
    end;
  end;
end;

//and finally routine to send data from server to client:
procedure TRemoteForm.ServerXmitToClient(var Buffer:
                             TPVBYTEArray; count: integer);
var
  aThread: TPeerThread;
  i : integer;
begin
  try
    try
      while activePollRequest.Count > 0 do begin
    Athread := TPeerThread(activePollRequest.First);
    activePollRequest.Delete(0);

        if not aThread.Terminated then begin
          aThread.connection.WriteInteger(count);
      for i := 0 to count-1 do
            aThread.connection.WriteInteger(buffer[i]);
    end;
      end;
    finally
      // had some cleanup code here earlier
    end;
  except
      on e: exception do begin
      debugLogmessage('Exception in '+
                          'TRemoteForm.ServerXmitToClient'
                          +^M^J+e.Message);
    end;
  end;
end;

//end of code

So, have I created a monster?  I keep thinking that I should look
at using the old Borland sockets again.

Your thoughts are appreciated.

-KS

Replies:

www.cryer.info
Managed Newsgroup Archive