Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Indy und Wiedervervendung von procedure (https://www.delphipraxis.net/173504-indy-und-wiedervervendung-von-procedure.html)

hesch21 28. Feb 2013 15:05

Indy und Wiedervervendung von procedure
 
Vermutlich bin ich wieder mal mit Blindheit beschlagen! Ich habe eine applikation sowohl als Desktop-Anwendung und als Service. Und das ganze ist zur Hauptsache ein recht komplexer TCP/IP-Server, mit den Indy-Komponenten gebaut. Und logischerweise sind in den beiden Applikationen eine Vielzahl der Funktionen genau gleich. Das ist alles bei 'normalen' procedures oder functions kein Problem. Die habe ich einfach in eine separate Unit ausgelagert. Aber wie mache ich das mit den ellenlangen IdTCPServerExecute procedures? Die sind (fast) baugleich in beiden Applikationen (die Unterschiede habe ich bereits mit einer Compiler-Bedingung abgefangen), aber die Procedure, welche ja gleichzeitig ein Thread ist, ist ja mit der Komponente der Form verknüpft (ja ich weiss, der Service hat nicht wirklich eine Form sondern nur eine Art Komponenten-Container).
Da es mir nun bereits mehrmals passiert ist, dass ich bei einer Änderung vergessen habe, diese in beiden Applikationen vorzunehmen, suche ich dringend nach einer Lösung, bei der ich den Code nur noch an einer Stelle habe.
Aber wie gesagt, ich komme nicht auf die Lösung. Für einen erleuchtenden Hinweis wäre ich dankbar.

sx2008 28. Feb 2013 15:26

AW: Indy und Wiedervervendung von procedure
 
Ich würde den gemeinsamen Code in eine (oder mehrere) Klasse(n) auslagern.
Diese Klasse(n) befindet sich wiederum in einer Unit, die von App und Service benützt wird.
Delphi-Quellcode:
TServerAblauf = class(TObject)
protected
  FServer : TIdTcpServer;
public
  constructor Create(server : TIdTcpServer);
  procedure Execute;
end;

constructor TServerAblauf.Create(server : TIdTcpServer);
begin
  inherited Create;
  FServer := server;
  // hier evtl. noch Events auf eigene Methoden richten
  FServer.OnDisconnect := self.DisconnectHandler;
end;

procedure TServerAblauf.Execute;
begin
  // dein Code
end;

hesch21 1. Mär 2013 08:43

AW: Indy und Wiedervervendung von procedure
 
Danke sx2008 für Deinen Tipp. Der Ansatz ist gut, nur...
Das OnExecute-Event vom Indy-TCPServer sieht wie folgt aus:
Delphi-Quellcode:
procedure IdTCPServerExecute(AContext: TIdContext);
Wie komme ich jetzt nach Deiner Methode an den AContext?
Ich müsste doch irgendwie die procedure gar nicht bei der Klasse definieren sondern im Constructor das OnExecute-Event definieren, aber das schaffe ich wieder nicht.

Blup 1. Mär 2013 10:24

AW: Indy und Wiedervervendung von procedure
 
Es ist vieleicht wichtig welche Indy-Version überhaupt verwendet wird.

Bei Indy-9 ist das Event so deklariert:
Delphi-Quellcode:
  TIdServerThreadEvent = procedure(AThread: TIdPeerThread) of object;
{...}
    property OnExecute: TIdServerThreadEvent read FOnExecute write FOnExecute;
Auf jeden Fall sind alle Events als "of object" vereinbart und erwarten damit die Methode einer Klasse. Also implementiere in deiner Klasse einfach die entsprechende Ereignismethode, so wie das Ereignis in deiner Version der Komponente definiert ist:
Delphi-Quellcode:
TServerAblauf = class(TObject)
protected
  FServer : TIdTcpServer;
  procedure DoExecute(AThread: TIdPeerThread);
public
  constructor Create(server : TIdTcpServer);
end;

constructor TServerAblauf.Create(server : TIdTcpServer);
begin
  inherited Create;
  FServer := server;
  // hier evtl. noch Events auf eigene Methoden richten
  FServer.OnExecute := DoExecute;
end;

procedure TServerAblauf.DoExecute(AThread: TIdPeerThread);
begin
  // Hier tun, was zu tun ist.

end;

hesch21 1. Mär 2013 11:55

AW: Indy und Wiedervervendung von procedure
 
Hallo Blup

ich benutze Indy-10. da ist die Definition
Code:
TIdServerThreadEvent = procedure(AContext: TIdContext) of object;

  TIdServerContext = class(TIdContext)
  protected
    FServer: TIdCustomTCPServer;
  public
    property Server: TIdCustomTCPServer read FServer;
  end;

  TIdServerContextClass = class of TIdServerContext;


    // Occurs in the context of the peer thread
    property OnExecute: TIdServerThreadEvent read FOnExecute write FOnExecute;
Also muss ich doch nur folgendes anpassen:
Code:
TServerAblauf = class(TObject)
protected
  FServer : TIdTcpServer;
  procedure DoExecute(AThread: TIdContext);
public
  constructor Create(server : TIdTcpServer);
end;

constructor TServerAblauf.Create(server : TIdTcpServer);
begin
  inherited Create;
  FServer := server;
  // hier evtl. noch Events auf eigene Methoden richten
  FServer.OnExecute := DoExecute;
end;

procedure TServerAblauf.DoExecute(AThread: TIdContext);
begin
  // Hier tun, was zu tun ist.

end;
Ich hoffe, ich sehe das richtig. Werde das am Wochenende austesten. Leider komme ich heute nicht mehr dazu.

bernhard_LA 1. Mär 2013 18:15

AW: Indy und Wiedervervendung von procedure
 
unter http://sourceforge.net/projects/indy10clieservr/ findest Du eine Shared Unit mit allen Funktionen zum Übertragen von Daten mit INDY , natürlich wegen reuse ausgelagert und geshared



( http://indy10clieservr.svn.sourcefor...04&view=markup )

hesch21 4. Mär 2013 12:41

AW: Indy und Wiedervervendung von procedure
 
Also, ich hab's getestet und es funktioniert tatsächlich. Hab sogar raus gefunden, dass der Aufruf aus der Main-Unit einfach in der dortigen OnExecute-Procedure der Server-Komponente mittels Aufruf von ServerAblauf.Create unter Angabe des Namen der Server-Komponente auf der Main-Unit erfolgt. Aber irgendwie bin ich mir nicht sicher, ob diese ausgelagerten Prozeduren 'selbstzerstörend' sind. Ich kreiere diese ja nun bei jedem OnExecute-Event, aber gebe diese nirgends explizit frei. Hab's mal probehalber mit einem Free als letzte Zeile der DoExecute-Procedure versucht, aber da bekomme danach Fehlermeldungen in IdThread.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz