Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Porting old Delphi2007 application using TServerSocket....
#1
So I have this old service application written in Delphi7 and maintained in Delphi2007 until about 2012.
Now it won't run anymore in Windows10 and I have decided to try a port to FreePascal so it can run on Linux.
The Indy10 suite is available in Lazarus as a package via Online Package Manager.

The server uses a TCP socket connection for user interaction (mainly configuration and data retrieval) and it was implemented at the time using TServerSocket that came with Delphi.

This won't obviously port so I thought that I could use Indy10 instead for that interface.
TIdTcpServer seems to be a natural replacement except for the fact that the TServerSocket is event driven...

The existing structure is a TService descendant which implements the Windows service. I know how to handle conversion to Linux for that.

But I would like some help into how I can port the communications between the remote client and the server using TidTcpServer.

This server uses TServerSocket in order to handle the communications and it implements the following event procedures:
Code:
sckServer: TServerSocket;
....
procedure sckClientConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure sckClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure sckClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure sckClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);

The sckClientConnect procedure handles the client connection and incoming commands as follows:

Code:
procedure TSuperStingRemoteServer.sckClientConnect(Sender: TObject; Socket: TCustomWinSocket);
{Create the remote handler and assign the communication to it}
var
  SSRC: TSSRemoteClientComm; //The communications object
  i: integer;
begin
  try
    FActivityTime := Now;
    i := sckServer.Socket.ActiveConnections;
    Log3RServer.StdLog('Active clients = ' + IntToStr(i));
    if i > 1 then
    begin
      Log3RServer.StdLog('Only one active client allowed!');
      Socket.Close;
      Exit;
    end;
    Log3RServer.StdLog('SSRemote - Client connect, IP=' + Socket.RemoteAddress + ' Host=' + Socket.RemoteHost);
    SSRC := TSSRemoteClientComm.Create(Socket, FRemoteServer);
    Socket.Data := SSRC;  {Keep pointer to handler with socket}
    SSRC.Log := Log3RComm;
    FRemoteServer.ClientCallback := SSRC.ClientCallback;
    Log3RServer.StdLog('SSRemote - initializing new SSRemote Client');
    SSRC.Initialize;
    SSRC.Log.StdLog('Socket communication channel opened to ' + Socket.RemoteAddress + ' Host='  + Socket.RemoteHost);
  except
    on E: Exception do
    begin
      Log3RServer.ErrLog('Exception during client connect: ' + E.Message);
    end;
  end;
end;

procedure TSuperStingRemoteServer.sckClientDisconnect(Sender: TObject;  Socket: TCustomWinSocket);
begin
  FRemoteServer.ClientCallback := NIL;
  LogStd('Client disconnect ' + Socket.RemoteAddress);
  FActivityTime := Now;
  if Socket.Data <> NIL then
  begin
    TSSRemoteClientComm(Socket.Data).OnDisconnect(Socket);
    TSSRemoteClientComm(Socket.Data).Free;
  end;
end;

procedure TSuperStingRemoteServer.sckClientRead(Sender: TObject;  Socket: TCustomWinSocket);
var
  RdData: string;
begin
  {Implement the socket data flow here by using the Data pointer to the handling object}
  RdData := Socket.ReceiveText;
  FActivityTime := Now;
  if Socket.Data <> NIL then
    TSSRemoteClientComm(Socket.Data).OnDataRead(RdData);
end;

procedure TSuperStingRemoteServer.sckClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  {Implement the socket error handling here}
  LogErr('Socket error detected, code: ' + IntToStr(ErrorCode));
  ErrorCode := 0; {To stop the socket from generating pop-up errors}
end;


So this system acts really just like a pass-through to the real communications object class dealing with all of the messaging and data transfers etc using the supplied socket when it was created.

Since Indy does not use events, how can I adapt this from TServerSocket to TidTcpServer?

Hopefully I will not have to modify too much inside the handler itself provided the network interface shown above is ported with the messaging in mind...
Note that the sckClientRead retrieves the client command text and just shuffles it over to the handler's OnDatRead method that takes the text as parameter, so it should really be decently simple provided one can get the receive text event off of the TidTcpServer object....

Grateful for any suggestions, it was quite a while since I wrote this application (started in 2004)....
Reply


Messages In This Thread
Porting old Delphi2007 application using TServerSocket.... - by BosseB - 07-05-2020, 01:08 PM

Forum Jump:


Users browsing this thread: 2 Guest(s)