Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Porting old Delphi2007 application using TServerSocket....
#14
(08-28-2020, 10:51 PM)rlebeau Wrote:
(08-28-2020, 08:53 PM)BosseB Wrote: In this case I have found a number of examples which for some reason do not work (Lazarus complains)

In what way exactly does it complain?

Cannot find identifiers etc...

But it seems like most examples are for earlier Indy versions than Indy10.

I managed to find these cases and fix them.


Quote:
(08-28-2020, 08:53 PM)BosseB Wrote: What should I put into the thread execute function on data reception to transfer it into the event?
Should I read the data in the thread or should I just push a notification that data are available and let the implementation of the event procedure read from the socket?

That is more of a design issue than a technical issue.  Use whichever design suits your needs.

I have tried to use an event function that contains the data but then I got an error from Lazarus.

With this in Execute it fails to compile:



Code:
type
  TCommRxEvent = procedure (Sender: TObject; Data: string) of object; // <= Is this a correct declaration?
...

  { TReadingThread }

  TReadingThread = class(TThread)
  protected
      FConn: TIdTCPConnection;
    FOnRxData: TCommRxEvent;
    FRxData: string;
      procedure Execute; override;
  public
      constructor Create(ACon: TIdTCPConnection);
    property OnRxData: TCommRxEvent read FOnRxData write FOnRxData;
  end;

...
procedure TReadingThread.Execute;
begin
  while not Terminated do
  begin
    if FConn.Connected then
    begin
      if FConn.IOHandler.CheckForDataOnSource(10) then
      begin
        if FConn.IOHandler.InputBuffer.Size > 0 then
        begin
          // read bytes from FConn up to InputBuffer.Size bytes ...
          FRxData := FConn.IOHandler.ReadString(FConn.IOHandler.InputBuffer.Size);
          //
          // process bytes as needed ...
          if Assigned(FOnRxData) then
            Synchronize(FOnRxData(Self, FRxData)); // <= Error here!
        end;
      end;
    end;
  end;
end;

The error message says:


Code:
tcpclientcomm.pas(141,47) Error: Incompatible type for arg no. 1: Got "untyped", expected "<procedure variable type of procedure of object;Register>"
And it does not mean much to me...



Quote:I will say, though, that you should not create the reading thread until after the TIdTCPClient has been connected first.  And then terminate and free the thread when the TIdTCPClient is being disconnected.

How can I do that, i.e. how do I know the connect and disconnect happened?


Quote:
(08-28-2020, 08:53 PM)BosseB Wrote: Here is my current (incomplete) state of the code:

If you are going to have the event pass a string, then the reading thread should handle all of the necessary reading and partial-message buffering and such, and pass only completed messages to the event.  Also, this would only work for text-based protocols.

Otherwise, I would suggest having the reading thread just read whatever raw bytes are on the socket at a time and pass the bytes as-is to the event, and let the event handler decide what to do with the bytes as needed.

Do you mean passing the data out in the event handler in a TIdBytes container?

Or should the event not contain the data and the reading be done by the handler itself?

I.e. the event is just a Synchronized notification and the socket read is done in the event implementation instead?


Seems like it would be better keep that from the caller and just provide the received data itself, that is at least what I thought a better encapsulation.

But then again, I have not managed to implement it correctly...
Reply


Messages In This Thread
RE: Porting old Delphi2007 application using TServerSocket.... - by BosseB - 08-29-2020, 06:20 AM

Forum Jump:


Users browsing this thread: 4 Guest(s)