Laden...

WCF von ein Server starten

Erstellt von Foufou vor 13 Jahren Letzter Beitrag vor 13 Jahren 4.356 Views
F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren
WCF von ein Server starten

hallo aller seits

Ich bin für jede Hilfe sehr dankbar denn ich Komme nicht weiter.
habe ein WCF definiert in 3.5 .Net.

Ich muss den Service von Server starten.. und den Status und andere Operationen von Client steuern "Status, Start, Stop.."

Wie kann ich aus den Client auf den gleichen Service Instance zugreifen den ich aus mein Host davor initialisiert und gestartet habe,
Ansonsten wird bei der Methode Status im Service Klasse eine NullReferenceException ausgelöst

Host Seite

   Uri httpUrl = new Uri("http://localhost:8090/ProcessController");
            ServiceHost host = new ServiceHost(typeof(Process.ProcessController), httpUrl);
            host.Open();
            Thread.CurrentThread.Name = "Main";
            
            controller = new ProcessController();
            w = new Thread(controller.StartProcess);
            w.Start(true);

Service:

    [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(IMyEvents))]
    public interface IMyContract
    {
        [OperationContract(IsOneWay = true)]
        void StartALL();

        [OperationContract(IsOneWay = true)]
        void StopProcess();

        [OperationContract(IsOneWay = true)]
        void StartProcess(Object s);

        [OperationContract]
        string Status();
    }

    public interface IMyEvents
    {
        [OperationContract(IsOneWay = true)]
        void Event1();
    }

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class ProcessController : IMyContract
    {
        public void StartProcess(object s)
         {
                 shouldStop = false;
                 Thread.Sleep(5000);
                 StartInit();
                  ....
          }

        public string Status()
        {
            string st = "";
            foreach (ProcObjects p in procObjects)
            {                st += " Process :  " + p.Process.GetProcessName + "\n";
                st += " Processs  state " + p.Process.State + "\n";
                st +=  "Process Status " + p.Process.GetState.state + "\n";
                st += " Thread Status  : " + p.Thread.IsAlive + "\n"; 
            }

            return st;
        }

}

Client Seite

proxy.Status
3.430 Beiträge seit 2007
vor 13 Jahren

Hallo Foufou,

du hast bei deinem ProcessControl den InstanceContextMode.PerCall gesetzt.
Dadurch wird bei jedem Call eine neue Instanz erstellst, was ja nicht das ist was du willst.

Verwende besser InstanceContextMode.Single damit du immer die gleiche Instanz hast.
Evtl. ist auch der PerSession-Mode was für dich.

Gruss
Michael

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

Danke für deine Antwort, Ich habe es jetzt getestet bekomme in die 2 Fälle immer noch eine
NullReferenceException... die Anfrage kommt an den Service schon aber die Objecte p sind immer noch Null 8o

Also es ist richtig wie ich vorgehe: dass man ganz einfach von ein Host den Service Classe mit

controller = new ProcessController();

instantieren kann.. und Auf die Methoden direkt zugreift beispiel

"controller.Stop()

?
Weil in alle Beispiel siehe ich nur Host.Open() und host.Close()
man kann nicht richtig nachvollziehen wie man von Host aus mit der Service Klasse Kommuniziert und arbeitet! Es wird meistens aufällig beschrieben von Client Seite X(

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo Foufou,

Also es ist richtig wie ich vorgehe: dass man ganz einfach von ein Host den Service Classe mit.....

Ich bin zwar nicht der WCF Experte aber das ist IMHO nicht logisch.
Dein WCF Service erstellt sich die Instanz schon selbst. Und wenn du dir an einem anderen Ort selbst eine Instanz erstellst dann ist es dem Service relativ egal.

Die Instanz wird AFAIK erst erstellt sobald sich der Client verbindet.
Der Unterschied zwischen den einzelnen Moden ist dass er die erstellte Instanz wiederverwendet oder eben nicht.

Aber selbst erstellen brauchst du die Instanz definitiv nicht, da diese dann unabhängig vom WCF Service läuft.

Gruss
Michael

S
902 Beiträge seit 2007
vor 13 Jahren

Die Instanz wird AFAIK erst erstellt sobald sich der Client verbindet.
Der Unterschied zwischen den einzelnen Moden ist dass er die erstellte Instanz wiederverwendet oder eben nicht.

Gruss
Michael

Bei Mode Single wird die Instanz erstellt wenn der Host startet.

Sonst ist das, was michlg schreibt richtig.
Was genau willst du denn machen?

mfg
serial

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

Ich will von Host aus den Service "Process" starten

   
        host.Open()
         controller = new ProcessController();
            w = new Thread(controller.StartProcess);
            w.Start(true)

die Methode "StartProcess" liegt natürlich im Service
... Jetzt will ich von mein Client den Process Steuern "Status" abfragen usw..
auch villeicht den Client Gui schließen und wenn Ich noch einmal es öffne der
Process auf dem Host "Threads" laufen weiter 🙁

S
902 Beiträge seit 2007
vor 13 Jahren

Der Host startet ja deinen Service.
Vom Client kannst du dann MEthoden auf diesem Aufrufen.
Der Service kann mit dem Client per Cllbacks kommunizieren, und darüber könntest du das schließen anfordern.

mfg
serial

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

wie schon von mir und serial gesagt brauchst du den ProcessController nicht selbst zu starten.
Das macht schon der WCF Service.

Dann kann der Client auf die dort erstellte Instanz zugreifen.
Wenn dort immer noch was null ist dann musst du in der ProcessController Klasse dafür sorgen dass sie sich selbst hilft.
Von Aussen bringt es dir nix wenn du eine zweite ProcessController instanz erstellst.

Beispiel: Ein Mieter beklagt sich beim Vermieter dass die Heizung nicht funktioniert.
Dieser stellt daraufhin ein neues Haus auf und repariert dort die Heizung.
Das macht den Mieter natürlich nicht glücklich da bei ihm immer noch das selbe Problem ist.

Und genau das machst du hier mit deiner selbst erstellten ProcessController-Instanz

Gruss
Michael

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

was ist wenn ich auch von Host Methoden aufrufen will? Ist das nicht möglich?
kann ich es so machen dass wenn ich den Host Starte die Threads auch starten?
MFG

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

Ok ich habe es verstanden... dass bedeutet dass der Process selbst irgendwie die Thread starten muss gleichzeitig wenn ich mein Host starte! 🤔
direkt von Host kann man nicht die Processe steuern
wie macheee ich dassss 😁

S
902 Beiträge seit 2007
vor 13 Jahren

HAllo,

irgendwie hab ich das gefühl, du solltest mal ein par wcf tutorials durcharbeiten.
Und ich verstehe nicht wieso du unbedingt nen extra thread starten willst....das ist eigentlich unnötig.

mfg
serial

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

Sorry das ich störe, aber ich komme nicht weiter...
Der host startet mein Service... das bedeutet die Methode

StartProcess()

"im Service" muss irgendwie aufgerufen werden?
soll ich eine Main Methode einfügen im Service? Das hat auch nicht funktioniert..

S
902 Beiträge seit 2007
vor 13 Jahren

Hallo,

StartProcess ruft der CLient auf, nciht der Host.
Der Host hostet deinen Service.

Wie gesagt, schau dir einfach mal ein beliebiges WCF Tutorial an, da wird dies beschrieben.

mfg
serial

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

ok danke... noch eine Frage wenn ich aus mein Client

proxy.StartProcess(true);

aufrufe denn Starte
der Process aber danach ragiert es nicht mehr auf
proxy.Status() oder proxy.Stop() ?
an was könnte es liegen?

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo Foufou,

ist das StartProcess ein blockierender Vorgang?
D.h. löst das auf dem Server irgendwas aus was längere Zeit dauert?

Weil man sollte immer darauf achten dass man den client nicht blockert, da ist besser wenn du diese Aktionen in einen Thread auslagerst.

Was meinst du überhaupt mit reagiert nicht mehr? Debugge mal durch den Code damit du siehst wo er hängen bleibt.

Gruss
Michael

F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

Danke für dein Antwort...

Ich habe versucht es auf einem Thread im Client zu lagern.. es hat sich nichts viel geändert..
mit der Methode StartProcess fangt eine Schleife die dauerhaft arbeiten muss!!
wenn ich die andere Methoden aufrufe die springen bis zu base.Channel.StopProcess(); ohne die Methode auf mein Server "serviceclasse" auszuführen.... die springt nicht in der Service klasse rein.. ignoriert es einfach und dann läuft der StartProcess weiter.

Mein wcf GUI sieht wie folgt aus:

        private static ServiceClient proxy;
        private static Thread w;
        IMyEvents evnt;
        InstanceContext eventCntx;

        public Window1()
        {
            evnt = new MySubscriber();
            eventCntx = new InstanceContext(evnt);
            proxy = new ServiceClient(eventCntx);

            //ThreadStart s = new ThreadStart(proxy.StartProcess(true));
            w = new Thread(proxy.StartProcess);

            w.Start(true);
            InitializeComponent();
        } 

und den Client

    class ServiceClient : DuplexClientBase<IMyContract>, IMyContract
    {

        public ServiceClient(InstanceContext eventCntx)
            : base(eventCntx)
        {

        }

        public void StopProcess()
        {
            base.Channel.StopProcess();
        }

        public void StartProcess(Object s)
        {
            base.Channel.StartProcess(s);
        }

        public string Status()
        {
            return base.Channel.Status();
        }
F
Foufou Themenstarter:in
42 Beiträge seit 2009
vor 13 Jahren

OK Ich bin jetzt ein bissien weiter...

Wenn Ich im Service,

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]

setze

kann ich StartProcess() führen als auch alle andere Operationen Status, Stop usw...
ohne Problem.
Aber bei jede neue Start von mein GUI (Client) fangt der Prozess von null an + den alten Prozess zu laufen (instanziiert neue)

Wenn ich den ConcurrencyMode auf Singel stelle dann
Habe ich das Problem dass es nicht mehr auf die anderen Operationen (status, stop) reagiert..
Ich kann den Gui zwar beenden aber nicht mehr neue starten

MFG