Announcement

Collapse
No announcement yet.

COM, DCOM COM+ Kap 3..3

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

  • COM, DCOM COM+ Kap 3..3

    Hallo Herr Kosch,

    Ich versuche grad Ihr Beispiel in Ihrem Buch nachzuvollziehen (Kap 3.3 - Singleton-Server)
    Der Hintergrund: Ich möchte eine ausführbares Programm per COM etwas 'fernsteuerbar' machen. Dabei soll ein Client nur diesen Prozess erzeugen, falls noch keiner da ist, andernfalls soll er auf einen vorhandenen Prozess zugreifen koennen.
    Die Initializion im Buch scheint mir etwas suspect:

    initialization
    {$IFDEF NO_SINGLETON}<Br>
    TAutoObjectFactory.Create(ComServer, TConnectXSrv, Class_ConnectXSrv,
    ciMultiInstance, tmApartment);<Br>
    {$ELSE}<Br>
    TSingletonAutoObjectFactory.Create(ComServer, TConnectXSrv, Class_ConnectXSrv,
    ciMultiInstance, tmApartment);<Br>
    {$ENDIF}<Br>
    end.<Br>

    Ist hier ein Druckfehler, oder gehoert das wirklich so ?

    Mein Client verhält sich im Moment so:

    Bei ersten Start erkennt er eine bereits laufen Instanz (das andere Programm, der Server also, wurde von Hand zuvor gestart)
    Nach dem Beenden und dem Neustart des Clients wird jedoch ein neuer Prozess erzeugt.
    Danke fuer Hinweise

    Frank Ambiel

  • #2
    Hallo,

    das Beispielprojekt verwendet die Möglichkeiten der bedingten Compilierung, um sowohl das Standardverhalten als auch den Singleton-Server zu implementieren (siehe Seite 175 2. Absatz). Auf die beiden ClassFactories gehe ich auf der Seite 177 ein. Je nachdem, ob die Zeile <i>{$DEFINE NO_SINGLETON}</i> auskommentiert ist oder nicht, ändert sich das Verhalten

    Comment


    • #3
      Hallo,

      kann ich denn auf diese Art das oben gewuenschte Verhalten erzeugen oder nicht ? Oder hab ich das falsch verstanden ?
      Bzw. warum findet dr Client beim ersten Start die laufende Instanz, Beim zweiten allerdings nicht ? ISt evt das einbeziehen der ROT notwendig ?

      Fragend Guck
      Fran

      Comment


      • #4
        Hallo,

        ich habe die beiden Projekte (Server und Client) nochmals ohne Änderungen compiliert und ausprobiert:<br>
        - Der 1. Client startet den Local Server und schickt einen Wert (Bsp: 200) zum Server <br>
        - Der 2. Client startet beim Aufruf <b>keinen</b> neuen Local Server, sondern liest die Daten aus, die der 1. Client vorher dort abgelegt hat.<br>
        - Der 3. Client .... (siehe 2. Client).

        Somit funktioniert der Singleton-Server von der CDROM zum Buch. Das Verhalten ändert sich auch nicht, wenn der Local Server vorher von Hand als Prozess gestartet wird und der 1. Client auf einen bereits laufenden Server trifft.

        Die ROT (Running Object Table) ist eine Alternative zum Singleton-Server, bei der allerdings sowohl der Server als der Client angepasst werden muss. Beim Singleton-Server betrifft die Änderung nur die Server-Seite

        Comment


        • #5
          Hallo,

          ich glaub ich hab mich da nicht verstaendlich genug ausgedrueck :

          1. Ich starte von Hand den Server (als Local Prozess) <br>

          2. Ich starte den Client 1 -> der laufende Server wird erkannt <br>

          3. Ich beende den Client 1 (ok) <br> -> der Server laeuft weiter ( da er von Hand gestartet wurde) <br>
          4. Ich starte den Client 1 erneut und jetzt wir der laufende Server nicht mehr erkannt <br>

          Und genau das ist mein Problem !

          Gruss
          Fran

          Comment


          • #6
            Hallo,

            das Problem bei der o.g. Reihenfolge liegt darin, das zum Zeitpunkt 3 kein Client einen Interface-Zeiger auf den Singleton-Server offen hält und der Local Server zudem nicht über COM, sondern normal als EXE gestartet wurde.

            Es gibt in meinen Augen nur 2 saubere Lösungen für dieses Problem: <br>
            1. Der Local Server wird nicht von Hand gestartet, sondern über einen Hilfs-Client, der die ganze Zeit über einen Interface-Zeiger offen hält. <br>
            2. Anstelle des Singleton-Prinzips über die angepasste ClassFactory nutzt der Local Server die ROT aus

            Comment


            • #7
              Hallo,

              ich habe meine Anwendung nachtraeglich mit der ComSchnittstelle versehen.

              Wenn ich jetzt die Anwendung nicht ueber Exe sonder ueber com starte muss ich die anderen objecte ja auch irgendwie erzeugen. Doch wie mach ich das eigentlich ?<br>
              In der Programm-Unit steht sowas wie :<br>
              Application.CreateForm(TfrmConnectX, frmConnectX);<br>
              Dies Form muss auf jeden Fall erzeugt werden.

              daher habe ich die Methode createComObject erweitert : <br>
              <pre>
              function TsingleTonAutoObjectFactory.createComObject(const Controller : IUnknown) : TComObject; <br>
              begin <br>
              if FCOMObj = nil then <br>
              begin
              FCOMObj := inherited CreateComObject(Controller);
              end;
              if frmConnectX = nil then
              frmConnectX := TfrmConnectX.Create(??);
              Result := FCOMObj;
              end;

              </pre>

              Doch wen geb ich da jetzt als owner richtigerweise an <br>

              Gruss
              Fran

              Comment


              • #8
                Hallo,

                es wird nach einer Lösung für ein Problem gesucht, das es gar nicht gibt. Wenn der Client über <i>CoMeinCOMObjekt.Create</i> eine Instanz des Local Servers erzeugt, startet die COL den Prozess. Die DPR wird dabei ganz normal abgearbeitet, so dass die Anwendung als EXE normal gestartet wird (nur mit dem Unterschied, dass CreateProcess von der COL und nicht vom Anwender ausgelöst wird). Der einzige Unterschied besteht darin, dass die VCL die Eigenschaft <b>StartMode</b> setzt:
                <pre>
                procedure TFormMain.FormCreate(Sender: TObject);
                begin
                if (Comserver.StartMode = smStandAlone) then
                begin
                FAutomation := False;
                StatusBar1.Panels[0].Text := 'StandAlone'
                end
                else
                begin
                FAutomation := True;
                StatusBar1.Panels[0].Text := 'Automation';
                end;
                end;
                </pre>
                Erst dann, wenn der Prozess (EXE) des Local Servers vollständig initialisiert ist, meldet die EXE die Class Factory bei der COL an, so dass erst danach die Instanz des COM-Objekts der Anwendung angefordert wird. Zu diesem Zeitpunkt "lebt" die normale Anwendung bereits. Daher darf die Class Factory die Formular-Instanz nicht erzeugen, denn diese ist zu diesem Zeitpunkt bereits vorhanden

                Comment


                • #9
                  Hallo,

                  dann muss irgendwas woanders schieflaufen, jedesmal wenn ich versuche den Server automatisch das erste mal zu starten (d. h. es laeuft noch gar keine Instanz), dann gibts Fehlermeldung die von der Methode CreateForm herruehren.
                  Doch, wie kann ich dies debuggen ? Das Problem tritt ja nur dann auf wenn der Server per Automation gestartet wird.
                  Die Fehlermeldung lautet jetzt 'Der RPC Server ist nicht verfuegbar', also irgenwas muss hier auch schiefgehen.

                  Gruss
                  Frank

                  Comment


                  • #10
                    Hallo,

                    in derartigen Fällen würde ich mit einem ganz neuen Projekt beginnen, das nur aus einem einzigen Formular mit nichts drauf besteht. Das wird funktionieren - so dass man dann einzeln die Besonderheiten des anderen Projekt dort einbaut, bis es nicht mehr funktioniert. Der letzte Schritt führt dann zur Ursache des Problems

                    Comment


                    • #11
                      Hallo Herr Kosch,

                      ich bin jetzt schon ein ganzes Stueck weiter :-) Die Sache war die : in meinem Server-Programm gibt es eine Stelle die das aktuelle Verzeichnis bestimmt.
                      Damit wird dann ein INI-Datei verabeitet, stimmt dies nicht mehr, geht's natuerlich schief.
                      Dies ist aber genau der Unterschied (darauf kann man auch nicht grad kommen, so wie ich das Problem beschrieben habe) Das Verzeichnis ist im Falle automatischer Start das Verzeichnis WinNt\System32.
                      Ciao - und Danke fuer die Tipps (und fuer den Fisch)
                      Fran

                      Comment

                      Working...
                      X