Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TIdTCPServer im Dienst kann nicht "resetet" werden... (https://www.delphipraxis.net/115383-tidtcpserver-im-dienst-kann-nicht-resetet-werden.html)

cherry 11. Jun 2008 11:50


TIdTCPServer im Dienst kann nicht "resetet" werden
 
hi

ich erstelle einen tcp server zur laufzeit (indy10) in meiner dienstanwendung, die kommunikation läuft wie gewünscht mit dem entsprechenden anderen tool...

nach der interaktion soll nun der tcp server neu "aufgesetzt" werden...
d.h. max connections := 0...

wenn eine exception auftritt, soll der server so zurückgesetzt werden, dass wieder eine eingehende verbindung angenommen wird...

damit alles sauber verläuft möchte ich die komponente zerstören und neu erstellen, ich kriegs aber einfach nicht hin...
hab schon 1000 varianten probiert ohne erfolg jedoch.

so sollte es z.b. aussehen:

Delphi-Quellcode:
// RE/ACTIVATE TCP SERVER
procedure TSisterWatch.ActivateTCPServer;
var
  i,port: Integer;
  Cont:TIdContext;
begin
  if fulllog then LogFile.Log(msg0045);

  if assigned(TCPServer) then
  begin
    if fulllog then LogFile.Log('1  assigned');
    if TCPServer.Active then
    begin

//// disconnect clients (it should not have some established)
//     for i:=TCPServer.Contexts.LockList.Count-1 downto 0 do
//     begin
//       Cont:=TIdContext(TCPServer.Contexts.LockList.Items[i]);
//       Cont.Connection.Disconnect;
//     end;
//     TCPServer.Contexts.Clear;
//     TCPServer.Contexts.UnLockList;

//      if fulllog then LogFile.Log('1.2  is active try to set inactive');
//      TCPServer.Active := false;
//      if fulllog then LogFile.Log('1.3  successfully deactivated');
    end;
    //if fulllog then LogFile.Log('2  deactivated');
    //TCPServer.Bindings.Clear;
    //if fulllog then LogFile.Log('3  bindings cleared');
    //TCPServer.Contexts.Clear;
    //if fulllog then LogFile.Log('4  contexts cleared');
    //FreeAndNil(TCPServer);
    if fulllog then LogFile.Log('cleanup instance');
    TCPServer.CleanupInstance;
    if fulllog then LogFile.Log('5- try to destroy');
    TCPServer.Free;
    if fulllog then LogFile.Log('5  destroyed');
  end;

  // create the server new
  TCPServer := TIdTCPServer.Create(Self);
  if fulllog then LogFile.Log('6  created new');
  // link server actions

  if assigned(TCPServer) then
  begin
    if fulllog then LogFile.Log('7  assigned');
    TCPServer.OnExecute := TCPServerExecute;
    if fulllog then LogFile.Log('8  applyed on execute');
    // enough error handling in TCPServerOnExecute...
    //TCPServer.OnException := TCPServerException;
    TCPServer.OnConnect := TCPServerConnect;
    if fulllog then LogFile.Log('9  applyed on connect');
    TCPServer.OnDisconnect := TCPServerDisconnect;
    if fulllog then LogFile.Log('10 applyed on disconnect');
    TCPServer.Active := false;
    if fulllog then LogFile.Log('11 active falsed');
    port := GetPort;
    if fulllog then LogFile.Log('12 get port');
    TCPServer.DefaultPort := port;
    if fulllog then LogFile.Log('13 set port');
    TCPServer.Active := True;
    if fulllog then LogFile.Log('14 activated now');
  end
  else
    if fulllog then LogFile.Log(msg0042);

  if fulllog then LogFile.Log('reactivate procedure ended..');
end;
da ichs nicht hinkriege den dienst zu debuggen, habe ich halt vorübergehend meldungen in ein log file umgeleitet, dasselbe passiert mit den exceptions...

die funktion wird in einem mit try except block ausgeführt, jedoch erhalte ich keine exception meldung...
wie auch immer die letzte meldung mit diesem code in meinem log ist: "-try to destroy"

Ich kann den TCPServer weder Active = False setzten noch freeen oder destroyen ... bei all diesen sachen bleibt der dienst einfach stehen..

worauf muss ich achten dass ich den server löschen und dann erneut erstellen kann?

Vjay 11. Jun 2008 12:17

Re: TIdTCPServer im Dienst kann nicht "resetet" we
 
Eine Vermutung von mir ist, dass er beim "free" versucht sämtliche aktiven (Indy)Threads zu beenden und irgend einer blockiert.

Workaround wäre evtl. den Socket zu schließen, also Active=false, dann einen Thread zu starten der das .free übernimmt. Im Grunde arbeitest du einfach weiter und überlässt die alte Komponente ihrem Schicksal, musst halt nur darauf achten, dass der Thread diese auch wirklich irgendwann zerstört bekommt.

Allgemein frage ich mich aber wozu dieser Handstand überhaupt gut sein soll ;)

cherry 11. Jun 2008 13:02

Re: TIdTCPServer im Dienst kann nicht "resetet" we
 
hi danke für deine schnelle antwort...

eigentlich würde es mir ja reichen alle verbingungen zu "kappen" und den server "neu zu starten"...
aber ich kann den server eben auch nicht TCPServer.Active = false setzen... denn anscheinend hat er schon damit ein problem...

und nur deshalb versuchte ich es mit diesem handstand...

eine idee warum ich den tcp server nicht auf active = false setzen kann?

DataCool 12. Jun 2008 19:40

Re: TIdTCPServer im Dienst kann nicht "resetet" we
 
Hi Cherry,

Du solltest bevor Du den Server auf Active false setzt solltest Du
alle aktiven Verbindungen trennen.
Am besten die Liste "Locken" rückwärts durch laufen(von hinten nach vorne)
dann schreibst Du in jede Client connection ein "Disconnect" Kommando,
damit der Client weiß das die Verbindung weg ist und erst danach schliesst
Du die Verbindung.

Dann den Threads etwas Zeit geben sich zu disconnecten z.b.
warten solange die Clientliste.count > 0

Danach Server.Active := false;
Die Eigenschaft ThreadTerminateTimeout(bin jetzt nicht sicher, ob's die bei Indy10 noch gibt)
sollte einen Wert > 0 haben.

Außerdem zur Sicherheit

try
TcpServer.Active := false;
except {} end;

Des Weiteren solltest Du auf den Developer-Snapshot 10.2.3 updaten.

Und zu guter letzt : Man kann einen Dienst debuggen !:

- BreakPoint setzen
- Dienst über Windows-Dienstmanager starten
- In Delphi "Start/Mit Prozess verbinden" wählen
- dann die Option "Systemprozesse anzeigen" wählen und mit Deinem Dienst verbinden
- danach Dein "Event auslösen", so das dein Breakpoint eintrifft

Greetz DataCool

cherry 13. Jun 2008 15:05

Re: TIdTCPServer im Dienst kann nicht "resetet" we
 
hi DataCool.... ;-)

das hab ich doch hier versucht?!
Delphi-Quellcode:
     //disconnect clients (it should not have some established)
     for i:=TCPServer.Contexts.LockList.Count-1 downto 0 do
     begin
       Cont:=TIdContext(TCPServer.Contexts.LockList.Items[i]);
       Cont.Connection.Disconnect;
     end;
     TCPServer.Contexts.Clear;
     TCPServer.Contexts.UnLockList;
konnte dann aber doch nicht deaktivieren...


Alle Zeitangaben in WEZ +1. Es ist jetzt 22: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