Announcement

Collapse
No announcement yet.

Serialisierung bei Übergabe des Callback-Interface trotz Multithread-Server?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Serialisierung bei Übergabe des Callback-Interface trotz Multithread-Server?

    Hallo,

    ich habe eine Client-Server-Anwendung nach dem Beispiel des Callback-Managers aus dem COM/DCOM-Buch von Herrn Kosch erstellt, die soweit auch ganz gut läuft.<p>
    Die Clients verteilen sich auf verschiedene Rechner im Netzwerk und greifen auf einen gemeinsamen Server zu, der die Clients verwaltet und im Bedarfsfall Nachrichten an diese versendet.
    Seit einiger Zeit gibt es jedoch Probleme beim Anmelden einiger Clients, die wir inzwischen auf schlechte/fehlerhafte Netzwerkeinstellungen zurückführen (möchten).
    Das Problem äußert sich dabei wie folgt:<p>
    Ein Client kann zwar innerhalb kürzester Zeit eine Verbindung zum Server aufbauen, bei der Übergabe des Callback-Interfaces scheint allerdings die Suche nach dem Clientrechner sehr lange zu dauern, in einigen Fällen sogar "ewig".<p>
    Bei der Fehlereingrenzung ist mir nun aufgefallen, daß leider auch die eigentlich nicht betroffenen Clients, die sich am Server anmelden wollen, warten müssen, bis die Rückverbindung eines anderen Clients endlich gefunden wurde - es liegt also offenbar eine Serialisierung vor.<p>
    1.)<p>
    Kann mir jemand erklären, wie der Aufbau der Rückverbindung zum Callback-Interface funktioniert?<br>(oder: Aus welchem Grund braucht der Aufbau der Verbindung zum Callback-Interface bei einigen Rechnern weniger als 1 Sekunde, bei anderen aber mehr als eine Minute?)<p>
    2.)<p>
    Gibt es eine Möglichkeit dem Server beizubringen, die Serialisierung bei der erstmaligen Übergabe des Callback-Interfaces aufzuheben?<p>
    <p>
    Danke im voraus<p>
    <p>
    Andreas

    PS: Die Serverapplikation läuft auf W2K, die Clients laufen auf NT bzw. W2K.

  • #2
    Hallo,<br>
    <br>
    ein solcher Effekt tritt u.a. auf, wenn unter den Standardeigenschaften <br>von DCOM (Client oder Server) und dort unter den DCOM-Protokollen<br> nicht TCP/IP als erstes Protokoll eingetragen ist.<br>
    <br>
    Möglicherweise trifft dies auch in Ihrem Falle zu?<br>
    <br>
    Schönen Gruß,<br>
    André Mellenthin<br>
    <br&gt

    Comment


    • #3
      Tatsächlich ist bei einigen Rechnern TCP/IP nicht als erstes Protokoll eingetragen. Ob das bei allen Clients den gewünschten Erfolg bringt muß ich aber erst noch testen.<br>
      Die Rechner, zu denen gar keine Rückverbindung aufgebaut werden konnte, waren im DHCP-Server falsch eingepflegt.<br>
      Bleibt trotzdem noch die Frage, wie ich im Server verhindere, daß in Zukunft bei einem ähnlichen Problem die Serialisierung (Punkt 2) das Verbinden anderer Clients behindert.

      Andrea

      Comment


      • #4
        Hallo,

        im Abschnitt "Vor- und Nachteile" des Buchkapitels über den Callback-Manager gehe ich extra darauf ein, dass alle Callbacks nacheinander abgearbeitet werden, um den Vorgang abbrechen zu können, wenn bereits ein Client "richtig" geantwortet hat. In meinem Beispiel nutzt der Callback-Manager für alle Rückrufe einen gemeinsamen Thread (da auch ein gemeinsames TDBChannel-Objekt für die Verwaltung aller Clients genutzt wird), so dass es hier zwangsläufig zu einem Stau kommt, wenn ein Client nicht reagiert.
        <pre>
        (* Der Callback-Manager ruft über diese Methode die
        registrierten Client-Interface-Methoden auf. *)

        procedure TDBChannel.BroadcastInfo(const UserName, Msg: WideString);
        var
        iCnt : Integer;
        begin
        for iCnt := 0 to DBUsers.Count - 1 do
        DBUsers[iCnt].Callback.OnMsg(UserName, Msg);
        end;
        </pre>

        Um dieses Verhalten zu ändern, muss der Callback-Manager für jeden Client-Rückruf einen <b>eigenen Thread</b> nutzen, wobei der vom Client erhaltene Interface-Zeiger entsprechend vorbereitet werden muss. Erst ab <i>Delphi for .NET</i> können wir auch mit Delphi auf die automatischen asynchronen Aufrufe zurückgreifen, aber mit Delphi 5,6,7 bleibt nichts anderes übrig, als in eigener Regie separate Threads zu nutzen, damit die anderen Clients nicht ebenfalls beeinträchtigt werden

        Comment


        • #5
          Das Problem tritt nicht erst beim Aufruf der Callback-Methode auf, sondern schon bei der erstmaligen Übergabe des Interface-Zeigers durch den Client.<br>
          Mit anderen Worten: Meine Connect-Funktion wird erst dann durchlaufen, wenn die Rückverbindung zum Client hergestellt wurde. Alle Aufrufe der Connect-Funktion anderer Clients warten, bis die Rückverbindung des ersten Clients gefunden wurde.<p>
          Dies wird gut deutlich, wenn ich gleich zu Beginn der Connect-Funktion ein paar Kontroll-Ausgaben mache.<p>
          Beispiel:<br>
          Client A braucht, wenn er sich alleine anmeldet, für den Aufbau der Rückverbindung 1 Minute.<br>
          Client B braucht, wenn er sich alleine anmeldet, für den Aufbau der Rückverbindung 1 Sekunde.<p>
          1. Client A versucht sich anzumelden.<br>
          2. Client B versucht sich anzumelden.<br>
          3. Es vergeht 1 Minute.<br>
          4. Es erfolgt die Kontrollausgabe der Connect-Funktion für Client A.<br>
          5. Es erfolgt die Kontrollausgabe der Connect-Funktion für Client B.<p>
          Wobei 4. und 5. dank Multithreading auch umgekehrt erfolgen können.<p>
          Wie stelle ich nun diese Serialisierung ab, zumal es ja auch den Fall geben kann, daß die Rückverbindung gar nicht hergestellt werden kann (s.o.)?<p>
          PS: Bereits angemeldete Clients können während der Blockade normal weiterarbeiten

          Comment


          • #6
            Hallo,

            auch in diesem Fall hat das Problem die gleiche Ursache. Der Callback-Manager aus meinem Buch nutzt nur einen einzigen Thread, um die Interface-Liste aller Callback-Interfaces zu verwalten (Anmeldevorgang) und dann auch einen Callback auszuführen. Solange der Manager "beschäftigt" ist, kann also auch kein neuer Eintrag hinzugefügt werden, so dass der Client B warten muss.

            Wenn das Problem beim Client A sofort beim ersten Zugriff passiert, scheint es so, als ob das Betriebssystem den Rechner vom Client A nicht direkt finden kann, sondern über Umwege suchen muss. Ein häufiger Grund dafür sind DNS-Probleme oder die nicht übereinstimmende Reihenfolge von UDP und TCP/IP (bei einem Mischbetrieb von NT4 + W2K). Wenn dieses Zeitproblem immer nur mit einem bestimmten Rechner auftritt und dieser unter NT 4 läuft, würde ich zuerst prüfen, ob dort UDP ganz oben in der Protokollliste steht und wenn ja, so ändern, dass TCP/IP vor UDP kommt (um den UDP-Timeout zu vermeiden).

            &gt;..daß die Rückverbindung gar nicht hergestellt werden kann ..

            Wenn ein Client eine DCOM-Version zum Server herstellen kann und dabei seinen Interface-Zeiger auf das eigene Callback-Interface übergibt, sollte der Gegenaufruf bei richtiger Netzwerkkonfiguration ebenfalls in jedem Fall erfolgreich sein. Um zu verhindern, dass zu einem späteren Callback-Zeitpunkt alle behindert werden, wenn ein Client offline ist, muss jeder Client in einem eigenen Thread zurückgerufen werden.
            &#10

            Comment

            Working...
            X